d3dx9: Fix memory access for images with less than 4 bytes per pixel (Valgrind). (try 2)
Matteo Bruni
matteo.mystral at gmail.com
Wed Feb 23 06:08:19 CST 2011
Since try 1 I removed the endianness stuff, as it is not taken into
account elsewhere, and I replaced the for loops with memcpy.
-------------- next part --------------
From 337ee51631a5f8fa53dce424692063ba24d7f183 Mon Sep 17 00:00:00 2001
From: Matteo Bruni <mbruni at codeweavers.com>
Date: Wed, 16 Feb 2011 02:39:21 +0100
Subject: d3dx9: Fix memory access for images with less than 4 bytes per pixel (Valgrind).
---
dlls/d3dx9_36/surface.c | 78 +++++++++++++++++++++++++++++++++++++---------
1 files changed, 62 insertions(+), 16 deletions(-)
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c
index 48cd2c2..961b4cf 100644
--- a/dlls/d3dx9_36/surface.c
+++ b/dlls/d3dx9_36/surface.c
@@ -598,6 +598,40 @@ static void init_argb_conversion_info(CONST PixelFormatDesc *srcformat, CONST Pi
}
}
+static DWORD dword_from_bytes(CONST BYTE *src, UINT bytes_per_pixel)
+{
+ DWORD ret = 0;
+ static BOOL fixme_once;
+
+ if(bytes_per_pixel > sizeof(DWORD)) {
+ if(!fixme_once) {
+ FIXME("Unsupported image: %u bytes per pixel\n", bytes_per_pixel);
+ fixme_once = TRUE;
+ }
+ bytes_per_pixel = sizeof(DWORD);
+ }
+
+ memcpy(&ret, src, bytes_per_pixel);
+ return ret;
+}
+
+static void dword_to_bytes(BYTE *dst, DWORD dword, UINT bytes_per_pixel)
+{
+ static BOOL fixme_once;
+
+ ZeroMemory(dst, bytes_per_pixel);
+
+ if(bytes_per_pixel > sizeof(DWORD)) {
+ if(!fixme_once) {
+ FIXME("Unsupported image: %u bytes per pixel\n", bytes_per_pixel);
+ fixme_once = TRUE;
+ }
+ bytes_per_pixel = sizeof(DWORD);
+ }
+
+ memcpy(dst, &dword, bytes_per_pixel);
+}
+
/************************************************************
* get_relevant_argb_components
*
@@ -618,20 +652,21 @@ static void get_relevant_argb_components(CONST struct argb_conversion_info *info
* Recombines the output of get_relevant_argb_components and converts
* it to the destination format.
*/
-static void make_argb_color(CONST struct argb_conversion_info *info, CONST DWORD *in, DWORD *out)
+static DWORD make_argb_color(CONST struct argb_conversion_info *info, CONST DWORD *in)
{
UINT i;
- *out = 0;
+ DWORD val = 0;
for(i = 0;i < 4;i++) {
if(info->process_channel[i]) {
/* necessary to make sure that e.g. an X4R4G4B4 white maps to an R8G8B8 white instead of 0xf0f0f0 */
signed int shift;
- for(shift = info->destshift[i]; shift > info->destformat->shift[i]; shift -= info->srcformat->bits[i]) *out |= in[i] << shift;
- *out |= (in[i] >> (info->destformat->shift[i] - shift)) << info->destformat->shift[i];
+ for(shift = info->destshift[i]; shift > info->destformat->shift[i]; shift -= info->srcformat->bits[i]) val |= in[i] << shift;
+ val |= (in[i] >> (info->destformat->shift[i] - shift)) << info->destformat->shift[i];
}
}
- *out |= info->channelmask; /* new channels are set to their maximal value */
+ val |= info->channelmask; /* new channels are set to their maximal value */
+ return val;
}
/************************************************************
@@ -668,23 +703,29 @@ static void copy_simple_data(CONST BYTE *src, UINT srcpitch, POINT srcsize,
}
for(y = 0;y < minheight;y++) {
- const BYTE *srcptr = src + y * srcpitch;
+ const BYTE *srcptr = src + y * srcpitch;
BYTE *destptr = dest + y * destpitch;
+ DWORD val = 0;
+
for(x = 0;x < minwidth;x++) {
/* extract source color components */
- if(srcformat->type == FORMAT_ARGB) get_relevant_argb_components(&conv_info, *(const DWORD*)srcptr, channels);
+ if(srcformat->type == FORMAT_ARGB) {
+ pixel = dword_from_bytes(srcptr, srcformat->bytes_per_pixel);
+ get_relevant_argb_components(&conv_info, pixel, channels);
+ }
/* recombine the components */
- if(destformat->type == FORMAT_ARGB) make_argb_color(&conv_info, channels, (DWORD*)destptr);
+ if(destformat->type == FORMAT_ARGB) val = make_argb_color(&conv_info, channels);
if(colorkey) {
- get_relevant_argb_components(&ck_conv_info, *(const DWORD*)srcptr, channels);
- make_argb_color(&ck_conv_info, channels, &pixel);
+ get_relevant_argb_components(&ck_conv_info, pixel, channels);
+ pixel = make_argb_color(&ck_conv_info, channels);
if(pixel == colorkey)
/* make this pixel transparent */
- *(DWORD *)destptr &= ~conv_info.destmask[0];
+ val &= ~conv_info.destmask[0];
}
+ dword_to_bytes(destptr, val, destformat->bytes_per_pixel);
srcptr += srcformat->bytes_per_pixel;
destptr += destformat->bytes_per_pixel;
}
@@ -732,21 +773,26 @@ static void point_filter_simple_data(CONST BYTE *src, UINT srcpitch, POINT srcsi
for(x = 0;x < destsize.x;x++) {
const BYTE *srcptr = bufptr + (x * srcsize.x / destsize.x) * srcformat->bytes_per_pixel;
+ DWORD val = 0;
/* extract source color components */
- if(srcformat->type == FORMAT_ARGB) get_relevant_argb_components(&conv_info, *(const DWORD*)srcptr, channels);
+ if(srcformat->type == FORMAT_ARGB) {
+ pixel = dword_from_bytes(srcptr, srcformat->bytes_per_pixel);
+ get_relevant_argb_components(&conv_info, pixel, channels);
+ }
/* recombine the components */
- if(destformat->type == FORMAT_ARGB) make_argb_color(&conv_info, channels, (DWORD*)destptr);
+ if(destformat->type == FORMAT_ARGB) val = make_argb_color(&conv_info, channels);
if(colorkey) {
- get_relevant_argb_components(&ck_conv_info, *(const DWORD*)srcptr, channels);
- make_argb_color(&ck_conv_info, channels, &pixel);
+ get_relevant_argb_components(&ck_conv_info, pixel, channels);
+ pixel = make_argb_color(&ck_conv_info, channels);
if(pixel == colorkey)
/* make this pixel transparent */
- *(DWORD *)destptr &= ~conv_info.destmask[0];
+ val &= ~conv_info.destmask[0];
}
+ dword_to_bytes(destptr, val, destformat->bytes_per_pixel);
destptr += destformat->bytes_per_pixel;
}
}
--
1.7.3.4
More information about the wine-patches
mailing list