Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
56e86b3d
Commit
56e86b3d
authored
Oct 13, 2009
by
Tony Wasserka
Committed by
Alexandre Julliard
Oct 16, 2009
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
d3dx9: Implement converting and copying ARGB surface data in D3DXLoadSurfaceFromMemory.
parent
942ec30a
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
181 additions
and
3 deletions
+181
-3
d3dx9_36_private.h
dlls/d3dx9_36/d3dx9_36_private.h
+16
-0
surface.c
dlls/d3dx9_36/surface.c
+115
-3
util.c
dlls/d3dx9_36/util.c
+50
-0
No files found.
dlls/d3dx9_36/d3dx9_36_private.h
View file @
56e86b3d
...
...
@@ -31,9 +31,25 @@
#include "d3dx9.h"
/* for internal use */
typedef
enum
_FormatType
{
FORMAT_ARGB
,
/* unsigned */
FORMAT_UNKNOWN
}
FormatType
;
typedef
struct
_PixelFormatDesc
{
D3DFORMAT
format
;
BYTE
bits
[
4
];
BYTE
shift
[
4
];
UINT
bytes_per_pixel
;
FormatType
type
;
}
PixelFormatDesc
;
HRESULT
map_view_of_file
(
LPCWSTR
filename
,
LPVOID
*
buffer
,
DWORD
*
length
);
HRESULT
load_resource_into_memory
(
HMODULE
module
,
HRSRC
resinfo
,
LPVOID
*
buffer
,
DWORD
*
length
);
const
PixelFormatDesc
*
get_format_info
(
D3DFORMAT
format
);
extern
const
ID3DXBufferVtbl
D3DXBuffer_Vtbl
;
/* ID3DXBUFFER */
...
...
dlls/d3dx9_36/surface.c
View file @
56e86b3d
...
...
@@ -323,6 +323,84 @@ HRESULT WINAPI D3DXLoadSurfaceFromResourceW(LPDIRECT3DSURFACE9 pDestSurface,
return
D3DXERR_INVALIDDATA
;
}
/************************************************************
* copy_simple_data
*
* Copies the source buffer to the destination buffer, performing
* any necessary format conversion and color keying.
* Works only for ARGB formats with 1 - 4 bytes per pixel.
*/
static
void
copy_simple_data
(
CONST
BYTE
*
src
,
UINT
srcpitch
,
POINT
srcsize
,
CONST
PixelFormatDesc
*
srcformat
,
CONST
BYTE
*
dest
,
UINT
destpitch
,
POINT
destsize
,
CONST
PixelFormatDesc
*
destformat
,
DWORD
dwFilter
)
{
DWORD
srcshift
[
4
],
destshift
[
4
];
DWORD
srcmask
[
4
],
destmask
[
4
];
BOOL
process_channel
[
4
];
DWORD
channels
[
4
];
DWORD
channelmask
=
0
;
UINT
minwidth
,
minheight
;
BYTE
*
srcptr
,
*
destptr
;
UINT
i
,
x
,
y
;
ZeroMemory
(
channels
,
sizeof
(
channels
));
ZeroMemory
(
process_channel
,
sizeof
(
process_channel
));
for
(
i
=
0
;
i
<
4
;
i
++
)
{
/* srcshift is used to extract the _relevant_ components */
srcshift
[
i
]
=
srcformat
->
shift
[
i
]
+
max
(
srcformat
->
bits
[
i
]
-
destformat
->
bits
[
i
],
0
);
/* destshift is used to move the components to the correct position */
destshift
[
i
]
=
destformat
->
shift
[
i
]
+
max
(
destformat
->
bits
[
i
]
-
srcformat
->
bits
[
i
],
0
);
srcmask
[
i
]
=
((
1
<<
srcformat
->
bits
[
i
])
-
1
)
<<
srcformat
->
shift
[
i
];
destmask
[
i
]
=
((
1
<<
destformat
->
bits
[
i
])
-
1
)
<<
destformat
->
shift
[
i
];
/* channelmask specifies bits which aren't used in the source format but in the destination one */
if
(
destformat
->
bits
[
i
])
{
if
(
srcformat
->
bits
[
i
])
process_channel
[
i
]
=
TRUE
;
else
channelmask
|=
destmask
[
i
];
}
}
minwidth
=
(
srcsize
.
x
<
destsize
.
x
)
?
srcsize
.
x
:
destsize
.
x
;
minheight
=
(
srcsize
.
y
<
destsize
.
y
)
?
srcsize
.
y
:
destsize
.
y
;
for
(
y
=
0
;
y
<
minheight
;
y
++
)
{
srcptr
=
(
BYTE
*
)(
src
+
y
*
srcpitch
);
destptr
=
(
BYTE
*
)(
dest
+
y
*
destpitch
);
for
(
x
=
0
;
x
<
minwidth
;
x
++
)
{
/* extract source color components */
if
(
srcformat
->
type
==
FORMAT_ARGB
)
{
const
DWORD
col
=
*
(
DWORD
*
)
srcptr
;
for
(
i
=
0
;
i
<
4
;
i
++
)
if
(
process_channel
[
i
])
channels
[
i
]
=
(
col
&
srcmask
[
i
])
>>
srcshift
[
i
];
}
/* recombine the components */
if
(
destformat
->
type
==
FORMAT_ARGB
)
{
DWORD
*
const
pixel
=
(
DWORD
*
)
destptr
;
*
pixel
=
0
;
for
(
i
=
0
;
i
<
4
;
i
++
)
{
if
(
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
=
destshift
[
i
];
shift
>
destformat
->
shift
[
i
];
shift
-=
srcformat
->
bits
[
i
])
*
pixel
|=
channels
[
i
]
<<
shift
;
*
pixel
|=
(
channels
[
i
]
>>
(
destformat
->
shift
[
i
]
-
shift
))
<<
destformat
->
shift
[
i
];
}
}
*
pixel
|=
channelmask
;
/* new channels are set to their maximal value */
}
srcptr
+=
srcformat
->
bytes_per_pixel
;
destptr
+=
destformat
->
bytes_per_pixel
;
}
}
}
/************************************************************
* D3DXLoadSurfaceFromMemory
*
...
...
@@ -350,7 +428,8 @@ HRESULT WINAPI D3DXLoadSurfaceFromResourceW(LPDIRECT3DSURFACE9 pDestSurface,
* E_FAIL, if SrcFormat is D3DFMT_UNKNOWN or the dimensions of pSrcRect are invalid
*
* NOTES
* pSrcRect specifies the dimensions of the source data
* pSrcRect specifies the dimensions of the source data;
* negative values for pSrcRect are allowed as we're only looking at the width and height anyway.
*
*/
HRESULT
WINAPI
D3DXLoadSurfaceFromMemory
(
LPDIRECT3DSURFACE9
pDestSurface
,
...
...
@@ -364,11 +443,44 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(LPDIRECT3DSURFACE9 pDestSurface,
DWORD
dwFilter
,
D3DCOLOR
Colorkey
)
{
TRACE
(
"stub
\n
"
);
CONST
PixelFormatDesc
*
srcformatdesc
,
*
destformatdesc
;
D3DSURFACE_DESC
surfdesc
;
D3DLOCKED_RECT
lockrect
;
POINT
srcsize
,
destsize
;
HRESULT
hr
;
TRACE
(
"(void)
\n
"
);
if
(
!
pDestSurface
||
!
pSrcMemory
||
!
pSrcRect
)
return
D3DERR_INVALIDCALL
;
if
(
SrcFormat
==
D3DFMT_UNKNOWN
||
pSrcRect
->
left
>=
pSrcRect
->
right
||
pSrcRect
->
top
>=
pSrcRect
->
bottom
)
return
E_FAIL
;
return
E_NOTIMPL
;
if
(
dwFilter
!=
D3DX_FILTER_NONE
)
return
E_NOTIMPL
;
IDirect3DSurface9_GetDesc
(
pDestSurface
,
&
surfdesc
);
srcformatdesc
=
get_format_info
(
SrcFormat
);
destformatdesc
=
get_format_info
(
surfdesc
.
Format
);
if
(
srcformatdesc
->
type
==
FORMAT_UNKNOWN
||
srcformatdesc
->
bytes_per_pixel
>
4
)
return
E_NOTIMPL
;
if
(
destformatdesc
->
type
==
FORMAT_UNKNOWN
||
destformatdesc
->
bytes_per_pixel
>
4
)
return
E_NOTIMPL
;
srcsize
.
x
=
pSrcRect
->
right
-
pSrcRect
->
left
;
srcsize
.
y
=
pSrcRect
->
bottom
-
pSrcRect
->
top
;
if
(
!
pDestRect
)
{
destsize
.
x
=
surfdesc
.
Width
;
destsize
.
y
=
surfdesc
.
Height
;
}
else
{
destsize
.
x
=
pDestRect
->
right
-
pDestRect
->
left
;
destsize
.
y
=
pDestRect
->
bottom
-
pDestRect
->
top
;
}
hr
=
IDirect3DSurface9_LockRect
(
pDestSurface
,
&
lockrect
,
pDestRect
,
0
);
if
(
FAILED
(
hr
))
return
D3DXERR_INVALIDDATA
;
copy_simple_data
((
CONST
BYTE
*
)
pSrcMemory
,
SrcPitch
,
srcsize
,
srcformatdesc
,
(
CONST
BYTE
*
)
lockrect
.
pBits
,
lockrect
.
Pitch
,
destsize
,
destformatdesc
,
dwFilter
);
IDirect3DSurface9_UnlockRect
(
pDestSurface
);
return
D3D_OK
;
}
/************************************************************
...
...
dlls/d3dx9_36/util.c
View file @
56e86b3d
...
...
@@ -20,6 +20,37 @@
#include "wine/debug.h"
#include "d3dx9_36_private.h"
/************************************************************
* pixel format table providing info about number of bytes per pixel,
* number of bits per channel and format type.
*
* Call get_format_info to request information about a specific format.
*/
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 */
};
/************************************************************
* map_view_of_file
*
...
...
@@ -102,3 +133,22 @@ HRESULT load_resource_into_memory(HMODULE module, HRSRC resinfo, LPVOID *buffer,
return
S_OK
;
}
/************************************************************
* get_format_info
*
* Returns information about the specified format.
* If the format is unsupported, it's filled with the D3DFMT_UNKNOWN desc.
*
* PARAMS
* format [I] format whose description is queried
* desc [O] pointer to a StaticPixelFormatDesc structure
*
*/
const
PixelFormatDesc
*
get_format_info
(
D3DFORMAT
format
)
{
unsigned
int
i
=
0
;
while
(
formats
[
i
].
format
!=
format
&&
formats
[
i
].
format
!=
D3DFMT_UNKNOWN
)
i
++
;
return
&
formats
[
i
];
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment