[PATCH 1/5] d3dx9: Implement loading luminance/alpha data in D3DXLoadSurfaceFromMemory().
Henri Verbeet
hverbeet at codeweavers.com
Thu Mar 8 13:27:12 CST 2012
---
dlls/d3dx9_36/d3dx9_36_private.h | 7 ++
dlls/d3dx9_36/surface.c | 167 ++++++++++++++++++++++++++++++-------
dlls/d3dx9_36/util.c | 53 ++++++++-----
3 files changed, 176 insertions(+), 51 deletions(-)
diff --git a/dlls/d3dx9_36/d3dx9_36_private.h b/dlls/d3dx9_36/d3dx9_36_private.h
index ed46402..95006e4 100644
--- a/dlls/d3dx9_36/d3dx9_36_private.h
+++ b/dlls/d3dx9_36/d3dx9_36_private.h
@@ -32,6 +32,11 @@
#define ARRAY_SIZE(array) (sizeof(array)/sizeof(*array))
+struct vec4
+{
+ float x, y, z, w;
+};
+
/* for internal use */
typedef enum _FormatType {
FORMAT_ARGB, /* unsigned */
@@ -44,6 +49,8 @@ typedef struct _PixelFormatDesc {
BYTE shift[4];
UINT bytes_per_pixel;
FormatType type;
+ void (*from_rgba)(const struct vec4 *src, struct vec4 *dst);
+ void (*to_rgba)(const struct vec4 *src, struct vec4 *dst);
} PixelFormatDesc;
HRESULT map_view_of_file(LPCWSTR filename, LPVOID *buffer, DWORD *length) DECLSPEC_HIDDEN;
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c
index ca1699b..f436c53 100644
--- a/dlls/d3dx9_36/surface.c
+++ b/dlls/d3dx9_36/surface.c
@@ -670,6 +670,57 @@ static DWORD make_argb_color(CONST struct argb_conversion_info *info, CONST DWOR
return val;
}
+static void format_to_vec4(const PixelFormatDesc *format, const DWORD *src, struct vec4 *dst)
+{
+ DWORD mask;
+
+ if (format->bits[1])
+ {
+ mask = (1 << format->bits[1]) - 1;
+ dst->x = (float)((*src >> format->shift[1]) & mask) / mask;
+ }
+ else
+ dst->x = 1.0f;
+
+ if (format->bits[2])
+ {
+ mask = (1 << format->bits[2]) - 1;
+ dst->y = (float)((*src >> format->shift[2]) & mask) / mask;
+ }
+ else
+ dst->y = 1.0f;
+
+ if (format->bits[3])
+ {
+ mask = (1 << format->bits[3]) - 1;
+ dst->z = (float)((*src >> format->shift[3]) & mask) / mask;
+ }
+ else
+ dst->z = 1.0f;
+
+ if (format->bits[0])
+ {
+ mask = (1 << format->bits[0]) - 1;
+ dst->w = (float)((*src >> format->shift[0]) & mask) / mask;
+ }
+ else
+ dst->w = 1.0f;
+}
+
+static void format_from_vec4(const PixelFormatDesc *format, const struct vec4 *src, DWORD *dst)
+{
+ *dst = 0;
+
+ if (format->bits[1])
+ *dst |= (DWORD)(src->x * ((1 << format->bits[1]) - 1) + 0.5f) << format->shift[1];
+ if (format->bits[2])
+ *dst |= (DWORD)(src->y * ((1 << format->bits[2]) - 1) + 0.5f) << format->shift[2];
+ if (format->bits[3])
+ *dst |= (DWORD)(src->z * ((1 << format->bits[3]) - 1) + 0.5f) << format->shift[3];
+ if (format->bits[0])
+ *dst |= (DWORD)(src->w * ((1 << format->bits[0]) - 1) + 0.5f) << format->shift[0];
+}
+
/************************************************************
* copy_simple_data
*
@@ -685,6 +736,7 @@ static void copy_simple_data(CONST BYTE *src, UINT srcpitch, POINT srcsize,
D3DCOLOR colorkey)
{
struct argb_conversion_info conv_info, ck_conv_info;
+ const PixelFormatDesc *ck_format = NULL;
DWORD channels[4], pixel;
UINT minwidth, minheight;
UINT x, y;
@@ -695,33 +747,58 @@ static void copy_simple_data(CONST BYTE *src, UINT srcpitch, POINT srcsize,
minwidth = (srcsize.x < destsize.x) ? srcsize.x : destsize.x;
minheight = (srcsize.y < destsize.y) ? srcsize.y : destsize.y;
- if(colorkey) {
- /* color keys are always represented in D3DFMT_A8R8G8B8 format */
- const PixelFormatDesc *ckformatdesc;
-
- ckformatdesc = get_format_info(D3DFMT_A8R8G8B8);
- init_argb_conversion_info(srcformat, ckformatdesc, &ck_conv_info);
+ if (colorkey)
+ {
+ /* Color keys are always represented in D3DFMT_A8R8G8B8 format. */
+ ck_format = get_format_info(D3DFMT_A8R8G8B8);
+ init_argb_conversion_info(srcformat, ck_format, &ck_conv_info);
}
for(y = 0;y < minheight;y++) {
const BYTE *srcptr = src + y * srcpitch;
BYTE *destptr = dest + y * destpitch;
- DWORD val = 0;
+ DWORD val;
for(x = 0;x < minwidth;x++) {
/* extract source color components */
pixel = dword_from_bytes(srcptr, srcformat->bytes_per_pixel);
- get_relevant_argb_components(&conv_info, pixel, channels);
- /* recombine the components */
- val = make_argb_color(&conv_info, channels);
+ if (!srcformat->to_rgba && !destformat->from_rgba)
+ {
+ get_relevant_argb_components(&conv_info, pixel, channels);
+ val = make_argb_color(&conv_info, channels);
+
+ if (colorkey)
+ {
+ get_relevant_argb_components(&ck_conv_info, pixel, channels);
+ pixel = make_argb_color(&ck_conv_info, channels);
+ if (pixel == colorkey)
+ val &= ~conv_info.destmask[0];
+ }
+ }
+ else
+ {
+ struct vec4 color, tmp;
+
+ format_to_vec4(srcformat, &pixel, &color);
+ if (srcformat->to_rgba)
+ srcformat->to_rgba(&color, &tmp);
+ else
+ tmp = color;
+
+ if (ck_format)
+ {
+ format_from_vec4(ck_format, &tmp, &pixel);
+ if (pixel == colorkey)
+ tmp.w = 0.0f;
+ }
+
+ if (destformat->from_rgba)
+ destformat->from_rgba(&tmp, &color);
+ else
+ color = tmp;
- if(colorkey) {
- get_relevant_argb_components(&ck_conv_info, pixel, channels);
- pixel = make_argb_color(&ck_conv_info, channels);
- if(pixel == colorkey)
- /* make this pixel transparent */
- val &= ~conv_info.destmask[0];
+ format_from_vec4(destformat, &color, &val);
}
dword_to_bytes(destptr, val, destformat->bytes_per_pixel);
@@ -751,6 +828,7 @@ static void point_filter_simple_data(CONST BYTE *src, UINT srcpitch, POINT srcsi
D3DCOLOR colorkey)
{
struct argb_conversion_info conv_info, ck_conv_info;
+ const PixelFormatDesc *ck_format = NULL;
DWORD channels[4], pixel;
UINT x, y;
@@ -758,12 +836,11 @@ static void point_filter_simple_data(CONST BYTE *src, UINT srcpitch, POINT srcsi
ZeroMemory(channels, sizeof(channels));
init_argb_conversion_info(srcformat, destformat, &conv_info);
- if(colorkey) {
- /* color keys are always represented in D3DFMT_A8R8G8B8 format */
- const PixelFormatDesc *ckformatdesc;
-
- ckformatdesc = get_format_info(D3DFMT_A8R8G8B8);
- init_argb_conversion_info(srcformat, ckformatdesc, &ck_conv_info);
+ if (colorkey)
+ {
+ /* Color keys are always represented in D3DFMT_A8R8G8B8 format. */
+ ck_format = get_format_info(D3DFMT_A8R8G8B8);
+ init_argb_conversion_info(srcformat, ck_format, &ck_conv_info);
}
for(y = 0;y < destsize.y;y++) {
@@ -772,21 +849,47 @@ 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;
+ DWORD val;
/* extract source color components */
pixel = dword_from_bytes(srcptr, srcformat->bytes_per_pixel);
- get_relevant_argb_components(&conv_info, pixel, channels);
- /* recombine the components */
- val = make_argb_color(&conv_info, channels);
+ if (!srcformat->to_rgba && !destformat->from_rgba)
+ {
+ get_relevant_argb_components(&conv_info, pixel, channels);
+ val = make_argb_color(&conv_info, channels);
+
+ if (colorkey)
+ {
+ get_relevant_argb_components(&ck_conv_info, pixel, channels);
+ pixel = make_argb_color(&ck_conv_info, channels);
+ if (pixel == colorkey)
+ val &= ~conv_info.destmask[0];
+ }
+ }
+ else
+ {
+ struct vec4 color, tmp;
+
+ format_to_vec4(srcformat, &pixel, &color);
+ if (srcformat->to_rgba)
+ srcformat->to_rgba(&color, &tmp);
+ else
+ tmp = color;
+
+ if (ck_format)
+ {
+ format_from_vec4(ck_format, &tmp, &pixel);
+ if (pixel == colorkey)
+ tmp.w = 0.0f;
+ }
+
+ if (destformat->from_rgba)
+ destformat->from_rgba(&tmp, &color);
+ else
+ color = tmp;
- if(colorkey) {
- get_relevant_argb_components(&ck_conv_info, pixel, channels);
- pixel = make_argb_color(&ck_conv_info, channels);
- if(pixel == colorkey)
- /* make this pixel transparent */
- val &= ~conv_info.destmask[0];
+ format_from_vec4(destformat, &color, &val);
}
dword_to_bytes(destptr, val, destformat->bytes_per_pixel);
diff --git a/dlls/d3dx9_36/util.c b/dlls/d3dx9_36/util.c
index ddb54c3..0ed315c 100644
--- a/dlls/d3dx9_36/util.c
+++ b/dlls/d3dx9_36/util.c
@@ -22,6 +22,20 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
+static void la_from_rgba(const struct vec4 *rgba, struct vec4 *la)
+{
+ la->x = rgba->x * 0.2125f + rgba->y * 0.7154f + rgba->z * 0.0721f;
+ la->w = rgba->w;
+}
+
+static void la_to_rgba(const struct vec4 *la, struct vec4 *rgba)
+{
+ rgba->x = la->x;
+ rgba->y = la->x;
+ rgba->z = la->x;
+ rgba->w = la->w;
+}
+
/************************************************************
* pixel format table providing info about number of bytes per pixel,
* number of bits per channel and format type.
@@ -30,25 +44,26 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
*/
static const PixelFormatDesc formats[] =
{
- /* format bits per channel shifts per channel bpp type */
- { D3DFMT_R8G8B8, { 0, 8, 8, 8 }, { 0, 16, 8, 0 }, 3, FORMAT_ARGB },
- { D3DFMT_A8R8G8B8, { 8, 8, 8, 8 }, { 24, 16, 8, 0 }, 4, FORMAT_ARGB },
- { D3DFMT_X8R8G8B8, { 0, 8, 8, 8 }, { 0, 16, 8, 0 }, 4, FORMAT_ARGB },
- { D3DFMT_A8B8G8R8, { 8, 8, 8, 8 }, { 24, 0, 8, 16 }, 4, FORMAT_ARGB },
- { D3DFMT_X8B8G8R8, { 0, 8, 8, 8 }, { 0, 0, 8, 16 }, 4, FORMAT_ARGB },
- { D3DFMT_R5G6B5, { 0, 5, 6, 5 }, { 0, 11, 5, 0 }, 2, FORMAT_ARGB },
- { D3DFMT_X1R5G5B5, { 0, 5, 5, 5 }, { 0, 10, 5, 0 }, 2, FORMAT_ARGB },
- { D3DFMT_A1R5G5B5, { 1, 5, 5, 5 }, { 15, 10, 5, 0 }, 2, FORMAT_ARGB },
- { D3DFMT_R3G3B2, { 0, 3, 3, 2 }, { 0, 5, 2, 0 }, 1, FORMAT_ARGB },
- { D3DFMT_A8R3G3B2, { 8, 3, 3, 2 }, { 8, 5, 2, 0 }, 2, FORMAT_ARGB },
- { D3DFMT_A4R4G4B4, { 4, 4, 4, 4 }, { 12, 8, 4, 0 }, 2, FORMAT_ARGB },
- { D3DFMT_X4R4G4B4, { 0, 4, 4, 4 }, { 0, 8, 4, 0 }, 2, FORMAT_ARGB },
- { D3DFMT_A2R10G10B10, { 2, 10, 10, 10 }, { 30, 20, 10, 0 }, 4, FORMAT_ARGB },
- { D3DFMT_A2B10G10R10, { 2, 10, 10, 10 }, { 30, 0, 10, 20 }, 4, FORMAT_ARGB },
- { D3DFMT_G16R16, { 0, 16, 16, 0 }, { 0, 0, 16, 0 }, 4, FORMAT_ARGB },
- { D3DFMT_A8, { 8, 0, 0, 0 }, { 0, 0, 0, 0 }, 1, FORMAT_ARGB },
-
- { D3DFMT_UNKNOWN, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, 0, FORMAT_UNKNOWN }, /* marks last element */
+ /* format bpc shifts bpp type from_rgba to_rgba */
+ {D3DFMT_R8G8B8, {0, 8, 8, 8}, { 0, 16, 8, 0}, 3, FORMAT_ARGB, NULL, NULL },
+ {D3DFMT_A8R8G8B8, {8, 8, 8, 8}, {24, 16, 8, 0}, 4, FORMAT_ARGB, NULL, NULL },
+ {D3DFMT_X8R8G8B8, {0, 8, 8, 8}, { 0, 16, 8, 0}, 4, FORMAT_ARGB, NULL, NULL },
+ {D3DFMT_A8B8G8R8, {8, 8, 8, 8}, {24, 0, 8, 16}, 4, FORMAT_ARGB, NULL, NULL },
+ {D3DFMT_X8B8G8R8, {0, 8, 8, 8}, { 0, 0, 8, 16}, 4, FORMAT_ARGB, NULL, NULL },
+ {D3DFMT_R5G6B5, {0, 5, 6, 5}, { 0, 11, 5, 0}, 2, FORMAT_ARGB, NULL, NULL },
+ {D3DFMT_X1R5G5B5, {0, 5, 5, 5}, { 0, 10, 5, 0}, 2, FORMAT_ARGB, NULL, NULL },
+ {D3DFMT_A1R5G5B5, {1, 5, 5, 5}, {15, 10, 5, 0}, 2, FORMAT_ARGB, NULL, NULL },
+ {D3DFMT_R3G3B2, {0, 3, 3, 2}, { 0, 5, 2, 0}, 1, FORMAT_ARGB, NULL, NULL },
+ {D3DFMT_A8R3G3B2, {8, 3, 3, 2}, { 8, 5, 2, 0}, 2, FORMAT_ARGB, NULL, NULL },
+ {D3DFMT_A4R4G4B4, {4, 4, 4, 4}, {12, 8, 4, 0}, 2, FORMAT_ARGB, NULL, NULL },
+ {D3DFMT_X4R4G4B4, {0, 4, 4, 4}, { 0, 8, 4, 0}, 2, FORMAT_ARGB, NULL, NULL },
+ {D3DFMT_A2R10G10B10, {2, 10, 10, 10}, {30, 20, 10, 0}, 4, FORMAT_ARGB, NULL, NULL },
+ {D3DFMT_A2B10G10R10, {2, 10, 10, 10}, {30, 0, 10, 20}, 4, FORMAT_ARGB, NULL, NULL },
+ {D3DFMT_G16R16, {0, 16, 16, 0}, { 0, 0, 16, 0}, 4, FORMAT_ARGB, NULL, NULL },
+ {D3DFMT_A8, {8, 0, 0, 0}, { 0, 0, 0, 0}, 1, FORMAT_ARGB, NULL, NULL },
+ {D3DFMT_A8L8, {8, 8, 0, 0}, { 8, 0, 0, 0}, 2, FORMAT_ARGB, la_from_rgba, la_to_rgba},
+ /* marks last element */
+ {D3DFMT_UNKNOWN, {0, 0, 0, 0}, { 0, 0, 0, 0}, 0, FORMAT_UNKNOWN, NULL, NULL },
};
--
1.7.3.4
More information about the wine-patches
mailing list