From ab16233318136da52c0cb5b4abf54ac0a2a78f4b Mon Sep 17 00:00:00 2001 From: Joel Teichroeb Date: Tue, 3 Apr 2012 16:54:05 -0700 Subject: GRAPHICS: Fix casting away const --- graphics/surface.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'graphics') diff --git a/graphics/surface.cpp b/graphics/surface.cpp index fcd702241a..c0f1046eae 100644 --- a/graphics/surface.cpp +++ b/graphics/surface.cpp @@ -295,7 +295,7 @@ Graphics::Surface *Surface::convertTo(const PixelFormat &dstFormat, const byte * assert(palette); for (int y = 0; y < h; y++) { - const byte *srcRow = (byte *)getBasePtr(0, y); + const byte *srcRow = (const byte *)getBasePtr(0, y); byte *dstRow = (byte *)surface->getBasePtr(0, y); for (int x = 0; x < w; x++) { @@ -317,7 +317,7 @@ Graphics::Surface *Surface::convertTo(const PixelFormat &dstFormat, const byte * } else { // Converting from high color to high color for (int y = 0; y < h; y++) { - const byte *srcRow = (byte *)getBasePtr(0, y); + const byte *srcRow = (const byte *)getBasePtr(0, y); byte *dstRow = (byte *)surface->getBasePtr(0, y); for (int x = 0; x < w; x++) { -- cgit v1.2.3 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 From db52618833920648b3ced9e2e8a7d692a4aba08f Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Sun, 8 Apr 2012 08:58:42 -0400 Subject: GRAPHICS: Add comments on which engines use the decoders --- graphics/decoders/bmp.h | 7 +++++++ graphics/decoders/jpeg.h | 7 +++++++ graphics/decoders/pict.h | 7 +++++++ 3 files changed, 21 insertions(+) (limited to 'graphics') diff --git a/graphics/decoders/bmp.h b/graphics/decoders/bmp.h index e11b12fad6..6360aa81c9 100644 --- a/graphics/decoders/bmp.h +++ b/graphics/decoders/bmp.h @@ -19,6 +19,13 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +/** + * @file + * Image decoder used in engines: + * - hugo + * - mohawk + */ + #ifndef GRAPHICS_DECODERS_BMP_H #define GRAPHICS_DECODERS_BMP_H diff --git a/graphics/decoders/jpeg.h b/graphics/decoders/jpeg.h index c566d5ad21..c74aa57ca1 100644 --- a/graphics/decoders/jpeg.h +++ b/graphics/decoders/jpeg.h @@ -20,6 +20,13 @@ * */ +/** + * @file + * Image decoder used in engines: + * - groovie + * - mohawk + */ + #ifndef GRAPHICS_JPEG_H #define GRAPHICS_JPEG_H diff --git a/graphics/decoders/pict.h b/graphics/decoders/pict.h index b1e45a6bc1..1d07df1ab9 100644 --- a/graphics/decoders/pict.h +++ b/graphics/decoders/pict.h @@ -20,6 +20,13 @@ * */ +/** + * @file + * Image decoder used in engines: + * - mohawk + * - sci + */ + #ifndef GRAPHICS_PICT_H #define GRAPHICS_PICT_H -- cgit v1.2.3 From 473a09786d0688e7ab9689be4f6e60172a288cb2 Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Sat, 14 Apr 2012 17:06:31 -0400 Subject: GRAPHICS: Make YUV410 conversion code use bilinear interpolation SVQ1 no longer looks blocky and now looks a lot closer to what QuickTime outputs --- graphics/yuv_to_rgb.cpp | 65 +++++++++++++++++++++++++++---------------------- graphics/yuv_to_rgb.h | 5 ++++ 2 files changed, 41 insertions(+), 29 deletions(-) (limited to 'graphics') diff --git a/graphics/yuv_to_rgb.cpp b/graphics/yuv_to_rgb.cpp index e0af267106..0abebf99a8 100644 --- a/graphics/yuv_to_rgb.cpp +++ b/graphics/yuv_to_rgb.cpp @@ -300,19 +300,8 @@ 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; @@ -320,26 +309,44 @@ void convertYUV410ToRGB(byte *dstPtr, int dstPitch, const YUVToRGBLookup *lookup 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(); + for (int y = 0; y < yHeight; y++) { + for (int x = 0; x < yWidth; x++) { + // Perform bilinear interpolation on the the chroma values + // Based on the algorithm found here: http://tech-algorithm.com/articles/bilinear-image-scaling/ + // Feel free to optimize further + int targetX = x >> 2; + int targetY = y >> 2; + int xDiff = x & 3; + int yDiff = y & 3; + int index = targetY * uvPitch + targetX; + + byte a = uSrc[index]; + byte b = uSrc[index + 1]; + byte c = uSrc[index + uvPitch]; + byte d = uSrc[index + uvPitch + 1]; + + byte u = (a * (4 - xDiff) * (4 - yDiff) + b * xDiff * (4 - yDiff) + + c * yDiff * (4 - xDiff) + d * xDiff * yDiff) >> 4; + + a = vSrc[index]; + b = vSrc[index + 1]; + c = vSrc[index + uvPitch]; + d = vSrc[index + uvPitch + 1]; + + byte v = (a * (4 - xDiff) * (4 - yDiff) + b * xDiff * (4 - yDiff) + + c * yDiff * (4 - xDiff) + d * xDiff * yDiff) >> 4; + + int16 cr_r = Cr_r_tab[v]; + int16 crb_g = Cr_g_tab[v] + Cb_g_tab[u]; + int16 cb_b = Cb_b_tab[u]; + const uint32 *L; + + PUT_PIXEL(ySrc[x], dstPtr); + dstPtr += sizeof(PixelInt); } - dstPtr += dstPitch * 3; - ySrc += (yPitch << 2) - yWidth; - uSrc += uvPitch - quarterWidth; - vSrc += uvPitch - quarterWidth; + dstPtr += dstPitch - yWidth * sizeof(PixelInt); + ySrc += yPitch; } } diff --git a/graphics/yuv_to_rgb.h b/graphics/yuv_to_rgb.h index 52ab2ebdfb..73a2c69d7d 100644 --- a/graphics/yuv_to_rgb.h +++ b/graphics/yuv_to_rgb.h @@ -67,6 +67,11 @@ void convertYUV420ToRGB(Graphics::Surface *dst, const byte *ySrc, const byte *uS /** * Convert a YUV410 image to an RGB surface * + * Since the chroma has a very low resolution in 410, we perform bilinear scaling + * on the two chroma planes to produce the image. The chroma planes must have + * at least one extra row that can be read from in order to produce a proper + * image (filled with 0x80). This is required in order to speed up this function. + * * @param dst the destination surface * @param ySrc the source of the y component * @param uSrc the source of the u component -- cgit v1.2.3 From b2de2cf85582fe62b96fcf36006816e16d023511 Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Mon, 16 Apr 2012 21:33:08 -0400 Subject: GRAPHICS: Improve the YUV410 conversion code speed some more --- graphics/yuv_to_rgb.cpp | 70 +++++++++++++++++++++++++++++++------------------ 1 file changed, 44 insertions(+), 26 deletions(-) (limited to 'graphics') diff --git a/graphics/yuv_to_rgb.cpp b/graphics/yuv_to_rgb.cpp index 0abebf99a8..78903d0cd8 100644 --- a/graphics/yuv_to_rgb.cpp +++ b/graphics/yuv_to_rgb.cpp @@ -300,6 +300,30 @@ 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 READ_QUAD(ptr, prefix) \ + byte prefix##A = ptr[index]; \ + byte prefix##B = ptr[index + 1]; \ + byte prefix##C = ptr[index + uvPitch]; \ + byte prefix##D = ptr[index + uvPitch + 1] + +#define DO_INTERPOLATION(out) \ + out = (out##A * (4 - xDiff) * (4 - yDiff) + out##B * xDiff * (4 - yDiff) + \ + out##C * yDiff * (4 - xDiff) + out##D * xDiff * yDiff) >> 4 + +#define DO_YUV410_PIXEL() \ + DO_INTERPOLATION(u); \ + DO_INTERPOLATION(v); \ + \ + cr_r = Cr_r_tab[v]; \ + crb_g = Cr_g_tab[v] + Cb_g_tab[u]; \ + cb_b = Cb_b_tab[u]; \ + \ + PUT_PIXEL(*ySrc, dstPtr); \ + dstPtr += sizeof(PixelInt); \ + \ + ySrc++; \ + 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) { // Keep the tables in pointers here to avoid a dereference on each pixel @@ -309,47 +333,41 @@ void convertYUV410ToRGB(byte *dstPtr, int dstPitch, const YUVToRGBLookup *lookup const int16 *Cb_b_tab = Cb_g_tab + 256; const uint32 *rgbToPix = lookup->_rgbToPix; + int quarterWidth = yWidth >> 2; + for (int y = 0; y < yHeight; y++) { - for (int x = 0; x < yWidth; x++) { + for (int x = 0; x < quarterWidth; x++) { // Perform bilinear interpolation on the the chroma values // Based on the algorithm found here: http://tech-algorithm.com/articles/bilinear-image-scaling/ // Feel free to optimize further - int targetX = x >> 2; int targetY = y >> 2; - int xDiff = x & 3; + int xDiff = 0; int yDiff = y & 3; - int index = targetY * uvPitch + targetX; - - byte a = uSrc[index]; - byte b = uSrc[index + 1]; - byte c = uSrc[index + uvPitch]; - byte d = uSrc[index + uvPitch + 1]; - - byte u = (a * (4 - xDiff) * (4 - yDiff) + b * xDiff * (4 - yDiff) + - c * yDiff * (4 - xDiff) + d * xDiff * yDiff) >> 4; - - a = vSrc[index]; - b = vSrc[index + 1]; - c = vSrc[index + uvPitch]; - d = vSrc[index + uvPitch + 1]; + int index = targetY * uvPitch + x; - byte v = (a * (4 - xDiff) * (4 - yDiff) + b * xDiff * (4 - yDiff) + - c * yDiff * (4 - xDiff) + d * xDiff * yDiff) >> 4; + // Declare some variables for the following macros + byte u, v; + int16 cr_r, crb_g, cb_b; + register const uint32 *L; - int16 cr_r = Cr_r_tab[v]; - int16 crb_g = Cr_g_tab[v] + Cb_g_tab[u]; - int16 cb_b = Cb_b_tab[u]; - const uint32 *L; + READ_QUAD(uSrc, u); + READ_QUAD(vSrc, v); - PUT_PIXEL(ySrc[x], dstPtr); - dstPtr += sizeof(PixelInt); + DO_YUV410_PIXEL(); + DO_YUV410_PIXEL(); + DO_YUV410_PIXEL(); + DO_YUV410_PIXEL(); } dstPtr += dstPitch - yWidth * sizeof(PixelInt); - ySrc += yPitch; + ySrc += yPitch - yWidth; } } +#undef READ_QUAD +#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) { // Sanity checks assert(dst && dst->pixels); -- cgit v1.2.3