aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/sword25/fmv/theora_decoder.cpp48
-rw-r--r--graphics/module.mk3
-rw-r--r--graphics/yuv_to_rgb.cpp240
-rw-r--r--graphics/yuv_to_rgb.h40
4 files changed, 285 insertions, 46 deletions
diff --git a/engines/sword25/fmv/theora_decoder.cpp b/engines/sword25/fmv/theora_decoder.cpp
index 4f5a006770..9aa7ead385 100644
--- a/engines/sword25/fmv/theora_decoder.cpp
+++ b/engines/sword25/fmv/theora_decoder.cpp
@@ -39,7 +39,8 @@
#ifdef USE_THEORADEC
#include "common/system.h"
#include "common/textconsole.h"
-#include "graphics/conversion.h"
+#include "common/util.h"
+#include "graphics/yuv_to_rgb.h"
#include "audio/decoders/raw.h"
#include "sword25/kernel/common.h"
@@ -508,16 +509,6 @@ uint32 TheoraDecoder::getElapsedTime() const {
return VideoDecoder::getElapsedTime();
}
-static void convertYUVtoBGRA(int y, int u, int v, byte *dst, Graphics::PixelFormat format) {
- byte r, g, b;
- Graphics::YUV2RGB(y, u, v, r, g, b);
-
- if (format.bytesPerPixel == 2)
- *((uint16 *)dst) = format.RGBToColor(r, g, b);
- else
- *((uint32 *)dst) = format.RGBToColor(r, g, b);
-}
-
enum TheoraYUVBuffers {
kBufferY = 0,
kBufferU = 1,
@@ -537,40 +528,7 @@ void TheoraDecoder::translateYUVtoRGBA(th_ycbcr_buffer &YUVBuffer) {
assert(YUVBuffer[kBufferU].height == YUVBuffer[kBufferY].height >> 1);
assert(YUVBuffer[kBufferV].height == YUVBuffer[kBufferY].height >> 1);
- const byte *ySrc = YUVBuffer[kBufferY].data;
- const byte *uSrc = YUVBuffer[kBufferU].data;
- const byte *vSrc = YUVBuffer[kBufferV].data;
- byte *dst = (byte *)_surface->pixels;
- int u = 0, v = 0;
-
- const int blockSize = YUVBuffer[kBufferY].width * getPixelFormat().bytesPerPixel;
- const int halfHeight = YUVBuffer[kBufferY].height >> 1;
- const int halfWidth = YUVBuffer[kBufferY].width >> 1;
- const int yStep = (YUVBuffer[kBufferY].stride << 1) - YUVBuffer[kBufferY].width;
- // The UV step is usually 0, since in most cases stride == width.
- // The asserts at the top ensure that the U and V steps are equal
- // (and they must always be equal)
- const int uvStep = YUVBuffer[kBufferU].stride - YUVBuffer[kBufferU].width;
- const int stride = YUVBuffer[kBufferY].stride;
-
- for (int h = 0; h < halfHeight; ++h) {
- for (int w = 0; w < halfWidth; ++w) {
- u = *uSrc++;
- v = *vSrc++;
-
- for (int i = 0; i <= 1; i++) {
- convertYUVtoBGRA(*ySrc, u, v, dst, getPixelFormat());
- convertYUVtoBGRA(*(ySrc + stride), u, v, dst + blockSize, getPixelFormat());
- ySrc++;
- dst += 4; // BGRA
- }
- }
-
- dst += blockSize;
- ySrc += yStep;
- uSrc += uvStep;
- vSrc += uvStep;
- }
+ Graphics::convertYUV420ToRGB(_surface, YUVBuffer[kBufferY].data, YUVBuffer[kBufferU].data, YUVBuffer[kBufferV].data, YUVBuffer[kBufferY].width, YUVBuffer[kBufferY].height, YUVBuffer[kBufferY].stride, YUVBuffer[kBufferU].stride);
}
} // End of namespace Sword25
diff --git a/graphics/module.mk b/graphics/module.mk
index 59621dc525..a9051c868a 100644
--- a/graphics/module.mk
+++ b/graphics/module.mk
@@ -25,7 +25,8 @@ MODULE_OBJS := \
thumbnail.o \
VectorRenderer.o \
VectorRendererSpec.o \
- wincursor.o
+ wincursor.o \
+ yuv_to_rgb.o
ifdef USE_SCALERS
MODULE_OBJS += \
diff --git a/graphics/yuv_to_rgb.cpp b/graphics/yuv_to_rgb.cpp
new file mode 100644
index 0000000000..b1107a7475
--- /dev/null
+++ b/graphics/yuv_to_rgb.cpp
@@ -0,0 +1,240 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+// The YUV to RGB conversion code is derived from SDL's YUV overlay code, which
+// in turn appears to be derived from mpeg_play. The following copyright
+// notices have been included in accordance with the original license. Please
+// note that the term "software" in this context only applies to the
+// buildLookup() and plotYUV*() functions below.
+
+// Copyright (c) 1995 The Regents of the University of California.
+// All rights reserved.
+//
+// Permission to use, copy, modify, and distribute this software and its
+// documentation for any purpose, without fee, and without written agreement is
+// hereby granted, provided that the above copyright notice and the following
+// two paragraphs appear in all copies of this software.
+//
+// IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+// DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+// OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+// CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+// ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+// PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+
+// Copyright (c) 1995 Erik Corry
+// All rights reserved.
+//
+// Permission to use, copy, modify, and distribute this software and its
+// documentation for any purpose, without fee, and without written agreement is
+// hereby granted, provided that the above copyright notice and the following
+// two paragraphs appear in all copies of this software.
+//
+// IN NO EVENT SHALL ERIK CORRY BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+// SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF
+// THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF ERIK CORRY HAS BEEN ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// ERIK CORRY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
+// BASIS, AND ERIK CORRY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
+// UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+
+// Portions of this software Copyright (c) 1995 Brown University.
+// All rights reserved.
+//
+// Permission to use, copy, modify, and distribute this software and its
+// documentation for any purpose, without fee, and without written agreement
+// is hereby granted, provided that the above copyright notice and the
+// following two paragraphs appear in all copies of this software.
+//
+// IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE TO ANY PARTY FOR
+// DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+// OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF BROWN
+// UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// BROWN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
+// BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
+// SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+
+#include "common/scummsys.h"
+#include "common/singleton.h"
+
+#include "graphics/surface.h"
+
+namespace Graphics {
+
+class YUVToRGBLookup {
+public:
+ YUVToRGBLookup(Graphics::PixelFormat format);
+ ~YUVToRGBLookup();
+
+ int16 *_colorTab;
+ uint32 *_rgbToPix;
+};
+
+YUVToRGBLookup::YUVToRGBLookup(Graphics::PixelFormat format) {
+ _colorTab = new int16[4 * 256]; // 2048 bytes
+
+ int16 *Cr_r_tab = &_colorTab[0 * 256];
+ int16 *Cr_g_tab = &_colorTab[1 * 256];
+ int16 *Cb_g_tab = &_colorTab[2 * 256];
+ int16 *Cb_b_tab = &_colorTab[3 * 256];
+
+ _rgbToPix = new uint32[3 * 768]; // 9216 bytes
+
+ uint32 *r_2_pix_alloc = &_rgbToPix[0 * 768];
+ uint32 *g_2_pix_alloc = &_rgbToPix[1 * 768];
+ uint32 *b_2_pix_alloc = &_rgbToPix[2 * 768];
+
+ int16 CR, CB;
+ int i;
+
+ // Generate the tables for the display surface
+
+ for (i = 0; i < 256; i++) {
+ // Gamma correction (luminescence table) and chroma correction
+ // would be done here. See the Berkeley mpeg_play sources.
+
+ CR = CB = (i - 128);
+ Cr_r_tab[i] = (int16) ( (0.419 / 0.299) * CR) + 0 * 768 + 256;
+ Cr_g_tab[i] = (int16) (-(0.299 / 0.419) * CR) + 1 * 768 + 256;
+ Cb_g_tab[i] = (int16) (-(0.114 / 0.331) * CB);
+ Cb_b_tab[i] = (int16) ( (0.587 / 0.331) * CB) + 2 * 768 + 256;
+ }
+
+ // Set up entries 0-255 in rgb-to-pixel value tables.
+ for (i = 0; i < 256; i++) {
+ r_2_pix_alloc[i + 256] = format.RGBToColor(i, 0, 0);
+ g_2_pix_alloc[i + 256] = format.RGBToColor(0, i, 0);
+ b_2_pix_alloc[i + 256] = format.RGBToColor(0, 0, i);
+ }
+
+ // Spread out the values we have to the rest of the array so that we do
+ // not need to check for overflow.
+ for (i = 0; i < 256; i++) {
+ r_2_pix_alloc[i] = r_2_pix_alloc[256];
+ r_2_pix_alloc[i + 512] = r_2_pix_alloc[511];
+ g_2_pix_alloc[i] = g_2_pix_alloc[256];
+ g_2_pix_alloc[i + 512] = g_2_pix_alloc[511];
+ b_2_pix_alloc[i] = b_2_pix_alloc[256];
+ b_2_pix_alloc[i + 512] = b_2_pix_alloc[511];
+ }
+}
+
+YUVToRGBLookup::~YUVToRGBLookup() {
+ delete[] _rgbToPix;
+ delete[] _colorTab;
+}
+
+class YUVToRGBManager : public Common::Singleton<YUVToRGBManager> {
+public:
+ const YUVToRGBLookup *getLookup(Graphics::PixelFormat format);
+
+private:
+ friend class Common::Singleton<SingletonBaseType>;
+ YUVToRGBManager();
+ ~YUVToRGBManager();
+
+ Graphics::PixelFormat _lastFormat;
+ YUVToRGBLookup *_lookup;
+};
+
+YUVToRGBManager::YUVToRGBManager() {
+ _lookup = 0;
+}
+
+YUVToRGBManager::~YUVToRGBManager() {
+ delete _lookup;
+}
+
+const YUVToRGBLookup *YUVToRGBManager::getLookup(Graphics::PixelFormat format) {
+ if (_lastFormat == format)
+ return _lookup;
+
+ delete _lookup;
+ _lookup = new YUVToRGBLookup(format);
+ _lastFormat = format;
+ return _lookup;
+}
+
+} // End of namespace Graphics
+
+DECLARE_SINGLETON(Graphics::YUVToRGBManager);
+
+#define YUVToRGBMan (Graphics::YUVToRGBManager::instance())
+
+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) {
+ const YUVToRGBLookup *lookup = YUVToRGBMan.getLookup(dst->format);
+
+ byte *dstPtr = (byte *)dst->pixels;
+
+ int halfHeight = yHeight >> 1;
+ int halfWidth = yWidth >> 1;
+
+ for (int h = 0; h < halfHeight; h++) {
+ for (int w = 0; w < halfWidth; w++) {
+ register 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];
+ ++uSrc;
+ ++vSrc;
+
+ PUT_PIXEL(*ySrc, dstPtr);
+ PUT_PIXEL(*(ySrc + yPitch), dstPtr + dst->pitch);
+ ySrc++;
+ dstPtr += dst->format.bytesPerPixel;
+ PUT_PIXEL(*ySrc, dstPtr);
+ PUT_PIXEL(*(ySrc + yPitch), dstPtr + dst->pitch);
+ ySrc++;
+ dstPtr += dst->format.bytesPerPixel;
+ }
+
+ dstPtr += dst->pitch;
+ ySrc += (yPitch << 1) - yWidth;
+ uSrc += uvPitch - halfWidth;
+ vSrc += uvPitch - halfWidth;
+ }
+}
+
+} // End of namespace Graphics
diff --git a/graphics/yuv_to_rgb.h b/graphics/yuv_to_rgb.h
new file mode 100644
index 0000000000..30f64ee570
--- /dev/null
+++ b/graphics/yuv_to_rgb.h
@@ -0,0 +1,40 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef GRAPHICS_YUV_TO_RGB_H
+#define GRAPHICS_YUV_TO_RGB_H
+
+#include "common/scummsys.h"
+#include "graphics/surface.h"
+
+namespace Graphics {
+
+struct Surface;
+
+void convertYUV420ToRGB(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