aboutsummaryrefslogtreecommitdiff
path: root/graphics
diff options
context:
space:
mode:
Diffstat (limited to 'graphics')
-rw-r--r--graphics/decoders/jpeg.cpp10
-rw-r--r--graphics/yuv_to_rgb.cpp46
-rw-r--r--graphics/yuv_to_rgb.h15
3 files changed, 63 insertions, 8 deletions
diff --git a/graphics/decoders/jpeg.cpp b/graphics/decoders/jpeg.cpp
index 0cd2388d52..a871377ca1 100644
--- a/graphics/decoders/jpeg.cpp
+++ b/graphics/decoders/jpeg.cpp
@@ -20,8 +20,8 @@
*
*/
-#include "graphics/conversion.h"
#include "graphics/pixelformat.h"
+#include "graphics/yuv_to_rgb.h"
#include "graphics/decoders/jpeg.h"
#include "common/debug.h"
@@ -81,13 +81,7 @@ const Surface *JPEGDecoder::getSurface() const {
const Graphics::Surface *uComponent = getComponent(2);
const Graphics::Surface *vComponent = getComponent(3);
- for (uint16 i = 0; i < _h; i++) {
- for (uint16 j = 0; j < _w; j++) {
- byte r = 0, g = 0, b = 0;
- YUV2RGB(*((const byte *)yComponent->getBasePtr(j, i)), *((const byte *)uComponent->getBasePtr(j, i)), *((const byte *)vComponent->getBasePtr(j, i)), r, g, b);
- *((uint32 *)_rgbSurface->getBasePtr(j, i)) = _rgbSurface->format.RGBToColor(r, g, b);
- }
- }
+ convertYUV444ToRGB(_rgbSurface, (byte *)yComponent->pixels, (byte *)uComponent->pixels, (byte *)vComponent->pixels, yComponent->w, yComponent->h, yComponent->pitch, uComponent->pitch);
return _rgbSurface;
}
diff --git a/graphics/yuv_to_rgb.cpp b/graphics/yuv_to_rgb.cpp
index feda48bf6d..ac7f217fee 100644
--- a/graphics/yuv_to_rgb.cpp
+++ b/graphics/yuv_to_rgb.cpp
@@ -199,6 +199,52 @@ namespace Graphics {
*((PixelInt *)(d)) = (L[cr_r] | L[crb_g] | L[cb_b])
template<typename PixelInt>
+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) {
+ // 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 < yHeight; h++) {
+ for (int w = 0; w < yWidth; 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;
+
+ PUT_PIXEL(*ySrc, dstPtr);
+ ySrc++;
+ dstPtr += sizeof(PixelInt);
+ }
+
+ dstPtr += dstPitch - yWidth * sizeof(PixelInt);
+ ySrc += yPitch - yWidth;
+ uSrc += uvPitch - yWidth;
+ vSrc += uvPitch - yWidth;
+ }
+}
+
+void convertYUV444ToRGB(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);
+
+ // Use a templated function to avoid an if check on every pixel
+ if (dst->format.bytesPerPixel == 2)
+ convertYUV444ToRGB<uint16>((byte *)dst->pixels, dst->pitch, lookup, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch);
+ else
+ convertYUV444ToRGB<uint32>((byte *)dst->pixels, dst->pitch, lookup, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch);
+}
+
+template<typename PixelInt>
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) {
int halfHeight = yHeight >> 1;
int halfWidth = yWidth >> 1;
diff --git a/graphics/yuv_to_rgb.h b/graphics/yuv_to_rgb.h
index 259ba09810..8e025042dc 100644
--- a/graphics/yuv_to_rgb.h
+++ b/graphics/yuv_to_rgb.h
@@ -23,6 +23,7 @@
/**
* @file
* YUV to RGB conversion used in engines:
+ * - mohawk
* - scumm (he)
* - sword25
*/
@@ -36,6 +37,20 @@
namespace Graphics {
/**
+ * Convert a YUV444 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
+ * @param yHeight the height of the y surface
+ * @param yPitch the pitch of the y surface
+ * @param uvPitch the pitch of the u and v surfaces
+ */
+void convertYUV444ToRGB(Graphics::Surface *dst, const byte *ySrc, const byte *uSrc, const byte *vSrc, int yWidth, int yHeight, int yPitch, int uvPitch);
+
+/**
* Convert a YUV420 image to an RGB surface
*
* @param dst the destination surface