2 * Copyright 2010 Christian Costa
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "d3dx9_private.h"
22 WINE_DEFAULT_DEBUG_CHANNEL(d3dx
);
24 HRESULT WINAPI
D3DXLoadVolumeFromFileA(IDirect3DVolume9
*dst_volume
, const PALETTEENTRY
*dst_palette
,
25 const D3DBOX
*dst_box
, const char *filename
, const D3DBOX
*src_box
, DWORD filter
,
26 D3DCOLOR color_key
, D3DXIMAGE_INFO
*info
)
32 TRACE("dst_volume %p, dst_palette %p, dst_box %p, filename %s, src_box %p, filter %#lx, "
33 "color_key 0x%08lx, info %p.\n",
34 dst_volume
, dst_palette
, dst_box
, debugstr_a(filename
), src_box
, filter
, color_key
, info
);
36 if (!dst_volume
|| !filename
) return D3DERR_INVALIDCALL
;
38 length
= MultiByteToWideChar(CP_ACP
, 0, filename
, -1, NULL
, 0);
39 filenameW
= HeapAlloc(GetProcessHeap(), 0, length
* sizeof(*filenameW
));
40 if (!filenameW
) return E_OUTOFMEMORY
;
41 MultiByteToWideChar(CP_ACP
, 0, filename
, -1, filenameW
, length
);
43 hr
= D3DXLoadVolumeFromFileW(dst_volume
, dst_palette
, dst_box
, filenameW
,
44 src_box
, filter
, color_key
, info
);
45 HeapFree(GetProcessHeap(), 0, filenameW
);
50 HRESULT WINAPI
D3DXLoadVolumeFromFileW(IDirect3DVolume9
*dst_volume
, const PALETTEENTRY
*dst_palette
,
51 const D3DBOX
*dst_box
, const WCHAR
*filename
, const D3DBOX
*src_box
, DWORD filter
,
52 D3DCOLOR color_key
, D3DXIMAGE_INFO
*info
)
58 TRACE("dst_volume %p, dst_palette %p, dst_box %p, filename %s, src_box %p, filter %#lx, "
59 "color_key 0x%08lx, info %p.\n",
60 dst_volume
, dst_palette
, dst_box
, debugstr_w(filename
), src_box
, filter
, color_key
, info
);
62 if (!dst_volume
|| !filename
) return D3DERR_INVALIDCALL
;
64 if (FAILED(map_view_of_file(filename
, &data
, &data_size
)))
65 return D3DXERR_INVALIDDATA
;
67 hr
= D3DXLoadVolumeFromFileInMemory(dst_volume
, dst_palette
, dst_box
,
68 data
, data_size
, src_box
, filter
, color_key
, info
);
69 UnmapViewOfFile(data
);
74 HRESULT WINAPI
D3DXLoadVolumeFromMemory(IDirect3DVolume9
*dst_volume
,
75 const PALETTEENTRY
*dst_palette
, const D3DBOX
*dst_box
, const void *src_memory
,
76 D3DFORMAT src_format
, UINT src_row_pitch
, UINT src_slice_pitch
,
77 const PALETTEENTRY
*src_palette
, const D3DBOX
*src_box
, DWORD filter
, D3DCOLOR color_key
)
81 D3DLOCKED_BOX locked_box
;
82 struct volume dst_size
, src_size
;
83 const struct pixel_format_desc
*src_format_desc
, *dst_format_desc
;
85 TRACE("dst_volume %p, dst_palette %p, dst_box %p, src_memory %p, src_format %#x, "
86 "src_row_pitch %u, src_slice_pitch %u, src_palette %p, src_box %p, filter %#lx, color_key 0x%08lx.\n",
87 dst_volume
, dst_palette
, dst_box
, src_memory
, src_format
, src_row_pitch
, src_slice_pitch
,
88 src_palette
, src_box
, filter
, color_key
);
90 if (!dst_volume
|| !src_memory
|| !src_box
) return D3DERR_INVALIDCALL
;
92 if (src_format
== D3DFMT_UNKNOWN
93 || src_box
->Left
>= src_box
->Right
94 || src_box
->Top
>= src_box
->Bottom
95 || src_box
->Front
>= src_box
->Back
)
98 if (filter
== D3DX_DEFAULT
)
99 filter
= D3DX_FILTER_TRIANGLE
| D3DX_FILTER_DITHER
;
101 IDirect3DVolume9_GetDesc(dst_volume
, &desc
);
103 src_size
.width
= src_box
->Right
- src_box
->Left
;
104 src_size
.height
= src_box
->Bottom
- src_box
->Top
;
105 src_size
.depth
= src_box
->Back
- src_box
->Front
;
109 dst_size
.width
= desc
.Width
;
110 dst_size
.height
= desc
.Height
;
111 dst_size
.depth
= desc
.Depth
;
115 if (dst_box
->Left
>= dst_box
->Right
|| dst_box
->Right
> desc
.Width
)
116 return D3DERR_INVALIDCALL
;
117 if (dst_box
->Top
>= dst_box
->Bottom
|| dst_box
->Bottom
> desc
.Height
)
118 return D3DERR_INVALIDCALL
;
119 if (dst_box
->Front
>= dst_box
->Back
|| dst_box
->Back
> desc
.Depth
)
120 return D3DERR_INVALIDCALL
;
122 dst_size
.width
= dst_box
->Right
- dst_box
->Left
;
123 dst_size
.height
= dst_box
->Bottom
- dst_box
->Top
;
124 dst_size
.depth
= dst_box
->Back
- dst_box
->Front
;
127 src_format_desc
= get_format_info(src_format
);
128 if (src_format_desc
->type
== FORMAT_UNKNOWN
)
131 dst_format_desc
= get_format_info(desc
.Format
);
132 if (dst_format_desc
->type
== FORMAT_UNKNOWN
)
135 if (desc
.Format
== src_format
136 && dst_size
.width
== src_size
.width
137 && dst_size
.height
== src_size
.height
138 && dst_size
.depth
== src_size
.depth
141 const BYTE
*src_addr
;
143 if (src_box
->Left
& (src_format_desc
->block_width
- 1)
144 || src_box
->Top
& (src_format_desc
->block_height
- 1)
145 || (src_box
->Right
& (src_format_desc
->block_width
- 1)
146 && src_size
.width
!= desc
.Width
)
147 || (src_box
->Bottom
& (src_format_desc
->block_height
- 1)
148 && src_size
.height
!= desc
.Height
))
150 FIXME("Source box (%u, %u, %u, %u) is misaligned\n",
151 src_box
->Left
, src_box
->Top
, src_box
->Right
, src_box
->Bottom
);
155 src_addr
= src_memory
;
156 src_addr
+= src_box
->Front
* src_slice_pitch
;
157 src_addr
+= (src_box
->Top
/ src_format_desc
->block_height
) * src_row_pitch
;
158 src_addr
+= (src_box
->Left
/ src_format_desc
->block_width
) * src_format_desc
->block_byte_count
;
160 hr
= IDirect3DVolume9_LockBox(dst_volume
, &locked_box
, dst_box
, 0);
161 if (FAILED(hr
)) return hr
;
163 copy_pixels(src_addr
, src_row_pitch
, src_slice_pitch
,
164 locked_box
.pBits
, locked_box
.RowPitch
, locked_box
.SlicePitch
,
165 &dst_size
, dst_format_desc
);
167 IDirect3DVolume9_UnlockBox(dst_volume
);
171 const BYTE
*src_addr
;
173 if (!is_conversion_from_supported(src_format_desc
)
174 || !is_conversion_to_supported(dst_format_desc
))
176 FIXME("Pixel format conversion is not implemented %#x -> %#x\n",
177 src_format_desc
->format
, dst_format_desc
->format
);
181 src_addr
= src_memory
;
182 src_addr
+= src_box
->Front
* src_slice_pitch
;
183 src_addr
+= src_box
->Top
* src_row_pitch
;
184 src_addr
+= src_box
->Left
* src_format_desc
->bytes_per_pixel
;
186 hr
= IDirect3DVolume9_LockBox(dst_volume
, &locked_box
, dst_box
, 0);
187 if (FAILED(hr
)) return hr
;
189 if ((filter
& 0xf) == D3DX_FILTER_NONE
)
191 convert_argb_pixels(src_memory
, src_row_pitch
, src_slice_pitch
, &src_size
, src_format_desc
,
192 locked_box
.pBits
, locked_box
.RowPitch
, locked_box
.SlicePitch
, &dst_size
, dst_format_desc
, color_key
,
197 if ((filter
& 0xf) != D3DX_FILTER_POINT
)
198 FIXME("Unhandled filter %#lx.\n", filter
);
200 point_filter_argb_pixels(src_addr
, src_row_pitch
, src_slice_pitch
, &src_size
, src_format_desc
,
201 locked_box
.pBits
, locked_box
.RowPitch
, locked_box
.SlicePitch
, &dst_size
, dst_format_desc
, color_key
,
205 IDirect3DVolume9_UnlockBox(dst_volume
);
211 HRESULT WINAPI
D3DXLoadVolumeFromFileInMemory(IDirect3DVolume9
*dst_volume
, const PALETTEENTRY
*dst_palette
,
212 const D3DBOX
*dst_box
, const void *src_data
, UINT src_data_size
, const D3DBOX
*src_box
,
213 DWORD filter
, D3DCOLOR color_key
, D3DXIMAGE_INFO
*src_info
)
217 D3DXIMAGE_INFO image_info
;
219 TRACE("dst_volume %p, dst_palette %p, dst_box %p, src_data %p, src_data_size %u, src_box %p, "
220 "filter %#lx, color_key 0x%08lx, src_info %p.\n",
221 dst_volume
, dst_palette
, dst_box
, src_data
, src_data_size
, src_box
,
222 filter
, color_key
, src_info
);
224 if (!dst_volume
|| !src_data
)
225 return D3DERR_INVALIDCALL
;
227 if (FAILED(hr
= D3DXGetImageInfoFromFileInMemory(src_data
, src_data_size
, &image_info
)))
232 if (src_box
->Right
> image_info
.Width
233 || src_box
->Bottom
> image_info
.Height
234 || src_box
->Back
> image_info
.Depth
)
235 return D3DERR_INVALIDCALL
;
243 box
.Right
= image_info
.Width
;
244 box
.Bottom
= image_info
.Height
;
246 box
.Back
= image_info
.Depth
;
250 if (image_info
.ImageFileFormat
!= D3DXIFF_DDS
)
252 FIXME("File format %#x is not supported yet\n", image_info
.ImageFileFormat
);
256 hr
= load_volume_from_dds(dst_volume
, dst_palette
, dst_box
, src_data
, &box
,
257 filter
, color_key
, &image_info
);
258 if (FAILED(hr
)) return hr
;
261 *src_info
= image_info
;
266 HRESULT WINAPI
D3DXLoadVolumeFromVolume(IDirect3DVolume9
*dst_volume
, const PALETTEENTRY
*dst_palette
,
267 const D3DBOX
*dst_box
, IDirect3DVolume9
*src_volume
, const PALETTEENTRY
*src_palette
,
268 const D3DBOX
*src_box
, DWORD filter
, D3DCOLOR color_key
)
273 D3DLOCKED_BOX locked_box
;
275 TRACE("dst_volume %p, dst_palette %p, dst_box %p, src_volume %p, src_palette %p, src_box %p, "
276 "filter %#lx, color_key 0x%08lx.\n",
277 dst_volume
, dst_palette
, dst_box
, src_volume
, src_palette
, src_box
, filter
, color_key
);
279 if (!dst_volume
|| !src_volume
) return D3DERR_INVALIDCALL
;
281 IDirect3DVolume9_GetDesc(src_volume
, &desc
);
285 box
.Left
= box
.Top
= 0;
286 box
.Right
= desc
.Width
;
287 box
.Bottom
= desc
.Height
;
289 box
.Back
= desc
.Depth
;
293 hr
= IDirect3DVolume9_LockBox(src_volume
, &locked_box
, NULL
, D3DLOCK_READONLY
);
294 if (FAILED(hr
)) return hr
;
296 hr
= D3DXLoadVolumeFromMemory(dst_volume
, dst_palette
, dst_box
,
297 locked_box
.pBits
, desc
.Format
, locked_box
.RowPitch
, locked_box
.SlicePitch
,
298 src_palette
, &box
, filter
, color_key
);
300 IDirect3DVolume9_UnlockBox(src_volume
);