include/mscvpdb.h: Use flexible array members for the rest of structures.
[wine.git] / dlls / d3dx9_36 / volume.c
blob06cae72c51ea68a8356b3f557a5ad8748bd54408
1 /*
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)
28 HRESULT hr;
29 int length;
30 WCHAR *filenameW;
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 = malloc(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 free(filenameW);
47 return hr;
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)
54 DWORD data_size;
55 HRESULT hr;
56 void *data;
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);
71 return hr;
74 static void set_d3dbox(D3DBOX *box, uint32_t left, uint32_t top, uint32_t right, uint32_t bottom, uint32_t front,
75 uint32_t back)
77 box->Left = left;
78 box->Top = top;
79 box->Right = right;
80 box->Bottom = bottom;
81 box->Front = front;
82 box->Back = back;
85 HRESULT WINAPI D3DXLoadVolumeFromMemory(IDirect3DVolume9 *dst_volume,
86 const PALETTEENTRY *dst_palette, const D3DBOX *dst_box, const void *src_memory,
87 D3DFORMAT src_format, UINT src_row_pitch, UINT src_slice_pitch,
88 const PALETTEENTRY *src_palette, const D3DBOX *src_box, DWORD filter, D3DCOLOR color_key)
90 const struct pixel_format_desc *src_format_desc, *dst_format_desc;
91 struct d3dx_pixels src_pixels, dst_pixels;
92 RECT dst_rect_aligned, dst_rect_unaligned;
93 D3DBOX dst_box_aligned, dst_box_tmp;
94 D3DLOCKED_BOX locked_box;
95 D3DVOLUME_DESC desc;
96 HRESULT hr;
98 TRACE("dst_volume %p, dst_palette %p, dst_box %p, src_memory %p, src_format %#x, "
99 "src_row_pitch %u, src_slice_pitch %u, src_palette %p, src_box %p, filter %#lx, color_key 0x%08lx.\n",
100 dst_volume, dst_palette, dst_box, src_memory, src_format, src_row_pitch, src_slice_pitch,
101 src_palette, src_box, filter, color_key);
103 if (!dst_volume || !src_memory || !src_box) return D3DERR_INVALIDCALL;
105 if (src_format == D3DFMT_UNKNOWN
106 || src_box->Left >= src_box->Right
107 || src_box->Top >= src_box->Bottom
108 || src_box->Front >= src_box->Back)
109 return E_FAIL;
111 if (filter == D3DX_DEFAULT)
112 filter = D3DX_FILTER_TRIANGLE | D3DX_FILTER_DITHER;
114 src_format_desc = get_format_info(src_format);
115 if (src_format_desc->type == FORMAT_UNKNOWN)
116 return E_NOTIMPL;
118 IDirect3DVolume9_GetDesc(dst_volume, &desc);
119 dst_format_desc = get_format_info(desc.Format);
120 if (dst_format_desc->type == FORMAT_UNKNOWN)
121 return E_NOTIMPL;
123 if (!dst_box)
125 set_d3dbox(&dst_box_tmp, 0, 0, desc.Width, desc.Height, 0, desc.Depth);
126 dst_box = &dst_box_tmp;
128 else
130 if (dst_box->Left >= dst_box->Right || dst_box->Right > desc.Width)
131 return D3DERR_INVALIDCALL;
132 if (dst_box->Top >= dst_box->Bottom || dst_box->Bottom > desc.Height)
133 return D3DERR_INVALIDCALL;
134 if (dst_box->Front >= dst_box->Back || dst_box->Back > desc.Depth)
135 return D3DERR_INVALIDCALL;
138 hr = d3dx_pixels_init(src_memory, src_row_pitch, src_slice_pitch,
139 src_palette, src_format, src_box->Left, src_box->Top, src_box->Right, src_box->Bottom,
140 src_box->Front, src_box->Back, &src_pixels);
141 if (FAILED(hr))
142 return hr;
144 get_aligned_rect(dst_box->Left, dst_box->Top, dst_box->Right, dst_box->Bottom, desc.Width, desc.Height,
145 dst_format_desc, &dst_rect_aligned);
146 set_d3dbox(&dst_box_aligned, dst_rect_aligned.left, dst_rect_aligned.top, dst_rect_aligned.right,
147 dst_rect_aligned.bottom, dst_box->Front, dst_box->Back);
149 hr = IDirect3DVolume9_LockBox(dst_volume, &locked_box, &dst_box_aligned, 0);
150 if (FAILED(hr))
151 return hr;
153 SetRect(&dst_rect_unaligned, dst_box->Left, dst_box->Top, dst_box->Right, dst_box->Bottom);
154 OffsetRect(&dst_rect_unaligned, -dst_rect_aligned.left, -dst_rect_aligned.top);
155 set_d3dx_pixels(&dst_pixels, locked_box.pBits, locked_box.RowPitch, locked_box.SlicePitch, dst_palette,
156 (dst_box_aligned.Right - dst_box_aligned.Left), (dst_box_aligned.Bottom - dst_box_aligned.Top),
157 (dst_box_aligned.Back - dst_box_aligned.Front), &dst_rect_unaligned);
159 hr = d3dx_load_pixels_from_pixels(&dst_pixels, dst_format_desc, &src_pixels, src_format_desc, filter,
160 color_key);
161 IDirect3DVolume9_UnlockBox(dst_volume);
162 return hr;
165 HRESULT WINAPI D3DXLoadVolumeFromFileInMemory(IDirect3DVolume9 *dst_volume, const PALETTEENTRY *dst_palette,
166 const D3DBOX *dst_box, const void *src_data, UINT src_data_size, const D3DBOX *src_box,
167 DWORD filter, D3DCOLOR color_key, D3DXIMAGE_INFO *src_info)
169 HRESULT hr;
170 D3DBOX box;
171 struct d3dx_image image;
172 struct d3dx_pixels pixels;
173 D3DXIMAGE_INFO image_info;
175 TRACE("dst_volume %p, dst_palette %p, dst_box %p, src_data %p, src_data_size %u, src_box %p, "
176 "filter %#lx, color_key 0x%08lx, src_info %p.\n",
177 dst_volume, dst_palette, dst_box, src_data, src_data_size, src_box,
178 filter, color_key, src_info);
180 if (!dst_volume || !src_data || !src_data_size)
181 return D3DERR_INVALIDCALL;
183 hr = d3dx_image_init(src_data, src_data_size, &image, 0, 0);
184 if (FAILED(hr))
185 return D3DXERR_INVALIDDATA;
187 d3dximage_info_from_d3dx_image(&image_info, &image);
188 if (src_box)
190 if (src_box->Right > image_info.Width
191 || src_box->Bottom > image_info.Height
192 || src_box->Back > image_info.Depth)
194 hr = D3DERR_INVALIDCALL;
195 goto exit;
198 box = *src_box;
200 else
202 set_d3dbox(&box, 0, 0, image_info.Width, image_info.Height, 0, image_info.Depth);
205 hr = d3dx_image_get_pixels(&image, 0, &pixels);
206 if (FAILED(hr))
207 goto exit;
209 hr = D3DXLoadVolumeFromMemory(dst_volume, dst_palette, dst_box, pixels.data, image_info.Format,
210 pixels.row_pitch, pixels.slice_pitch, pixels.palette, &box, filter, color_key);
211 if (SUCCEEDED(hr) && src_info)
212 *src_info = image_info;
214 exit:
215 d3dx_image_cleanup(&image);
216 return FAILED(hr) ? hr : D3D_OK;
219 HRESULT WINAPI D3DXLoadVolumeFromVolume(IDirect3DVolume9 *dst_volume, const PALETTEENTRY *dst_palette,
220 const D3DBOX *dst_box, IDirect3DVolume9 *src_volume, const PALETTEENTRY *src_palette,
221 const D3DBOX *src_box, DWORD filter, D3DCOLOR color_key)
223 HRESULT hr;
224 D3DBOX box;
225 D3DVOLUME_DESC desc;
226 D3DLOCKED_BOX locked_box;
228 TRACE("dst_volume %p, dst_palette %p, dst_box %p, src_volume %p, src_palette %p, src_box %p, "
229 "filter %#lx, color_key 0x%08lx.\n",
230 dst_volume, dst_palette, dst_box, src_volume, src_palette, src_box, filter, color_key);
232 if (!dst_volume || !src_volume) return D3DERR_INVALIDCALL;
234 IDirect3DVolume9_GetDesc(src_volume, &desc);
236 if (!src_box)
238 box.Left = box.Top = 0;
239 box.Right = desc.Width;
240 box.Bottom = desc.Height;
241 box.Front = 0;
242 box.Back = desc.Depth;
244 else box = *src_box;
246 hr = IDirect3DVolume9_LockBox(src_volume, &locked_box, NULL, D3DLOCK_READONLY);
247 if (FAILED(hr)) return hr;
249 hr = D3DXLoadVolumeFromMemory(dst_volume, dst_palette, dst_box,
250 locked_box.pBits, desc.Format, locked_box.RowPitch, locked_box.SlicePitch,
251 src_palette, &box, filter, color_key);
253 IDirect3DVolume9_UnlockBox(src_volume);
254 return hr;