aboutsummaryrefslogtreecommitdiff
path: root/graphics
diff options
context:
space:
mode:
authorMatthew Hoops2012-04-19 08:16:08 -0400
committerMatthew Hoops2012-04-19 08:16:24 -0400
commit9971e74c4c481f99401212b469e9c79185fa6e70 (patch)
treec45fe6d57cc35557e3c7ceb90b1e6f3edeb3aa2f /graphics
parent5ee569bce634d6704703239e665d865afc4e48fb (diff)
parent4520b115e97b494bd5d13599f27a5a339465f88e (diff)
downloadscummvm-rg350-9971e74c4c481f99401212b469e9c79185fa6e70.tar.gz
scummvm-rg350-9971e74c4c481f99401212b469e9c79185fa6e70.tar.bz2
scummvm-rg350-9971e74c4c481f99401212b469e9c79185fa6e70.zip
Merge remote branch 'upstream/master' into pegasus
Conflicts: base/plugins.cpp configure
Diffstat (limited to 'graphics')
-rw-r--r--graphics/decoders/bmp.h7
-rw-r--r--graphics/decoders/jpeg.h7
-rw-r--r--graphics/decoders/pict.h7
-rw-r--r--graphics/surface.cpp4
-rw-r--r--graphics/yuv_to_rgb.cpp85
-rw-r--r--graphics/yuv_to_rgb.h19
6 files changed, 127 insertions, 2 deletions
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
diff --git a/graphics/surface.cpp b/graphics/surface.cpp
index a96950d2c6..a37dd57e61 100644
--- a/graphics/surface.cpp
+++ b/graphics/surface.cpp
@@ -306,7 +306,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++) {
@@ -328,7 +328,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++) {
diff --git a/graphics/yuv_to_rgb.cpp b/graphics/yuv_to_rgb.cpp
index ac7f217fee..78903d0cd8 100644
--- a/graphics/yuv_to_rgb.cpp
+++ b/graphics/yuv_to_rgb.cpp
@@ -300,4 +300,89 @@ 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 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<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) {
+ // 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;
+
+ int quarterWidth = yWidth >> 2;
+
+ for (int y = 0; y < yHeight; y++) {
+ 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 targetY = y >> 2;
+ int xDiff = 0;
+ int yDiff = y & 3;
+ int index = targetY * uvPitch + x;
+
+ // Declare some variables for the following macros
+ byte u, v;
+ int16 cr_r, crb_g, cb_b;
+ register const uint32 *L;
+
+ READ_QUAD(uSrc, u);
+ READ_QUAD(vSrc, v);
+
+ DO_YUV410_PIXEL();
+ DO_YUV410_PIXEL();
+ DO_YUV410_PIXEL();
+ DO_YUV410_PIXEL();
+ }
+
+ dstPtr += dstPitch - yWidth * sizeof(PixelInt);
+ 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);
+ 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
diff --git a/graphics/yuv_to_rgb.h b/graphics/yuv_to_rgb.h
index 8e025042dc..73a2c69d7d 100644
--- a/graphics/yuv_to_rgb.h
+++ b/graphics/yuv_to_rgb.h
@@ -64,6 +64,25 @@ 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
+ *
+ * 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
+ * @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