aboutsummaryrefslogtreecommitdiff
path: root/graphics
diff options
context:
space:
mode:
Diffstat (limited to 'graphics')
-rw-r--r--graphics/yuv_to_rgb.cpp63
1 files changed, 37 insertions, 26 deletions
diff --git a/graphics/yuv_to_rgb.cpp b/graphics/yuv_to_rgb.cpp
index 831736cd75..037ea9a007 100644
--- a/graphics/yuv_to_rgb.cpp
+++ b/graphics/yuv_to_rgb.cpp
@@ -196,52 +196,63 @@ DECLARE_SINGLETON(Graphics::YUVToRGBManager);
namespace Graphics {
#define PUT_PIXEL(s, d) \
- L = &lookup->_rgbToPix[(s)]; \
- if (dst->format.bytesPerPixel == 2) \
- *((uint16 *)(d)) = (L[cr_r] | L[crb_g] | L[cb_b]); \
- else \
- *((uint32 *)(d)) = (L[cr_r] | L[crb_g] | L[cb_b])
-
-void convertYUV420ToRGB(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 & 1) == 0);
- assert((yHeight & 1) == 0);
-
- const YUVToRGBLookup *lookup = YUVToRGBMan.getLookup(dst->format);
-
- byte *dstPtr = (byte *)dst->pixels;
+ L = &rgbToPix[(s)]; \
+ *((PixelInt *)(d)) = (L[cr_r] | L[crb_g] | L[cb_b])
+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;
+ // 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 < halfHeight; h++) {
for (int w = 0; w < halfWidth; w++) {
- register uint32 *L;
+ register const uint32 *L;
- int16 cr_r = lookup->_colorTab[*vSrc + 0 * 256];
- int16 crb_g = lookup->_colorTab[*vSrc + 1 * 256] + lookup->_colorTab[*uSrc + 2 * 256];
- int16 cb_b = lookup->_colorTab[*uSrc + 3 * 256];
+ 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);
- PUT_PIXEL(*(ySrc + yPitch), dstPtr + dst->pitch);
+ PUT_PIXEL(*(ySrc + yPitch), dstPtr + dstPitch);
ySrc++;
- dstPtr += dst->format.bytesPerPixel;
+ dstPtr += sizeof(PixelInt);
PUT_PIXEL(*ySrc, dstPtr);
- PUT_PIXEL(*(ySrc + yPitch), dstPtr + dst->pitch);
+ PUT_PIXEL(*(ySrc + yPitch), dstPtr + dstPitch);
ySrc++;
- dstPtr += dst->format.bytesPerPixel;
+ dstPtr += sizeof(PixelInt);
}
- dstPtr += dst->pitch;
+ dstPtr += dstPitch;
ySrc += (yPitch << 1) - yWidth;
uSrc += uvPitch - halfWidth;
vSrc += uvPitch - halfWidth;
}
}
+void convertYUV420ToRGB(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 & 1) == 0);
+ assert((yHeight & 1) == 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)
+ convertYUV420ToRGB<uint16>((byte *)dst->pixels, dst->pitch, lookup, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch);
+ else
+ convertYUV420ToRGB<uint32>((byte *)dst->pixels, dst->pitch, lookup, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch);
+}
+
} // End of namespace Graphics