ReactOS  0.4.10-dev-238-gc84f398
surface.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2009-2010 Tony Wasserka
3  * Copyright (C) 2012 J√≥zef Kucia
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  *
19  */
20 
21 #include "config.h"
22 #include "wine/port.h"
23 
24 #include "d3dx9_private.h"
25 
26 #include "initguid.h"
27 #include "ole2.h"
28 #include "wincodec.h"
29 
30 #include "wine/wined3d.h"
31 
33 
34 
35 /* Wine-specific WIC GUIDs */
36 DEFINE_GUID(GUID_WineContainerFormatTga, 0x0c44fda1,0xa5c5,0x4298,0x96,0x85,0x47,0x3f,0xc1,0x7c,0xd3,0x22);
37 
38 static const struct
39 {
40  const GUID *wic_guid;
42 } wic_pixel_formats[] = {
43  { &GUID_WICPixelFormat8bppIndexed, D3DFMT_P8 },
44  { &GUID_WICPixelFormat1bppIndexed, D3DFMT_P8 },
45  { &GUID_WICPixelFormat4bppIndexed, D3DFMT_P8 },
46  { &GUID_WICPixelFormat8bppGray, D3DFMT_L8 },
47  { &GUID_WICPixelFormat16bppBGR555, D3DFMT_X1R5G5B5 },
48  { &GUID_WICPixelFormat16bppBGR565, D3DFMT_R5G6B5 },
49  { &GUID_WICPixelFormat24bppBGR, D3DFMT_R8G8B8 },
50  { &GUID_WICPixelFormat32bppBGR, D3DFMT_X8R8G8B8 },
51  { &GUID_WICPixelFormat32bppBGRA, D3DFMT_A8R8G8B8 }
52 };
53 
55 {
56  unsigned int i;
57 
58  for (i = 0; i < ARRAY_SIZE(wic_pixel_formats); i++)
59  {
61  return wic_pixel_formats[i].d3dformat;
62  }
63 
64  return D3DFMT_UNKNOWN;
65 }
66 
68 {
69  unsigned int i;
70 
71  for (i = 0; i < ARRAY_SIZE(wic_pixel_formats); i++)
72  {
73  if (wic_pixel_formats[i].d3dformat == format)
74  return wic_pixel_formats[i].wic_guid;
75  }
76 
77  return NULL;
78 }
79 
80 /* dds_header.flags */
81 #define DDS_CAPS 0x1
82 #define DDS_HEIGHT 0x2
83 #define DDS_WIDTH 0x4
84 #define DDS_PITCH 0x8
85 #define DDS_PIXELFORMAT 0x1000
86 #define DDS_MIPMAPCOUNT 0x20000
87 #define DDS_LINEARSIZE 0x80000
88 #define DDS_DEPTH 0x800000
89 
90 /* dds_header.caps */
91 #define DDS_CAPS_COMPLEX 0x8
92 #define DDS_CAPS_TEXTURE 0x1000
93 #define DDS_CAPS_MIPMAP 0x400000
94 
95 /* dds_header.caps2 */
96 #define DDS_CAPS2_CUBEMAP 0x200
97 #define DDS_CAPS2_CUBEMAP_POSITIVEX 0x400
98 #define DDS_CAPS2_CUBEMAP_NEGATIVEX 0x800
99 #define DDS_CAPS2_CUBEMAP_POSITIVEY 0x1000
100 #define DDS_CAPS2_CUBEMAP_NEGATIVEY 0x2000
101 #define DDS_CAPS2_CUBEMAP_POSITIVEZ 0x4000
102 #define DDS_CAPS2_CUBEMAP_NEGATIVEZ 0x8000
103 #define DDS_CAPS2_CUBEMAP_ALL_FACES ( DDS_CAPS2_CUBEMAP_POSITIVEX | DDS_CAPS2_CUBEMAP_NEGATIVEX \
104  | DDS_CAPS2_CUBEMAP_POSITIVEY | DDS_CAPS2_CUBEMAP_NEGATIVEY \
105  | DDS_CAPS2_CUBEMAP_POSITIVEZ | DDS_CAPS2_CUBEMAP_NEGATIVEZ )
106 #define DDS_CAPS2_VOLUME 0x200000
107 
108 /* dds_pixel_format.flags */
109 #define DDS_PF_ALPHA 0x1
110 #define DDS_PF_ALPHA_ONLY 0x2
111 #define DDS_PF_FOURCC 0x4
112 #define DDS_PF_RGB 0x40
113 #define DDS_PF_YUV 0x200
114 #define DDS_PF_LUMINANCE 0x20000
115 #define DDS_PF_BUMPLUMINANCE 0x40000
116 #define DDS_PF_BUMPDUDV 0x80000
117 
119 {
128 };
129 
131 {
147 };
148 
150 {
151  unsigned int i;
152  static const DWORD known_fourcc[] = {
153  D3DFMT_UYVY,
154  D3DFMT_YUY2,
157  D3DFMT_DXT1,
158  D3DFMT_DXT2,
159  D3DFMT_DXT3,
160  D3DFMT_DXT4,
161  D3DFMT_DXT5,
162  D3DFMT_R16F,
165  D3DFMT_R32F,
168  };
169 
170  for (i = 0; i < ARRAY_SIZE(known_fourcc); i++)
171  {
172  if (known_fourcc[i] == fourcc)
173  return fourcc;
174  }
175 
176  WARN("Unknown FourCC %#x\n", fourcc);
177  return D3DFMT_UNKNOWN;
178 }
179 
180 static const struct {
187 } rgb_pixel_formats[] = {
188  { 8, 0xe0, 0x1c, 0x03, 0, D3DFMT_R3G3B2 },
189  { 16, 0xf800, 0x07e0, 0x001f, 0x0000, D3DFMT_R5G6B5 },
190  { 16, 0x7c00, 0x03e0, 0x001f, 0x8000, D3DFMT_A1R5G5B5 },
191  { 16, 0x7c00, 0x03e0, 0x001f, 0x0000, D3DFMT_X1R5G5B5 },
192  { 16, 0x0f00, 0x00f0, 0x000f, 0xf000, D3DFMT_A4R4G4B4 },
193  { 16, 0x0f00, 0x00f0, 0x000f, 0x0000, D3DFMT_X4R4G4B4 },
194  { 16, 0x00e0, 0x001c, 0x0003, 0xff00, D3DFMT_A8R3G3B2 },
195  { 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000, D3DFMT_R8G8B8 },
196  { 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000, D3DFMT_A8R8G8B8 },
197  { 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000, D3DFMT_X8R8G8B8 },
198  { 32, 0x3ff00000, 0x000ffc00, 0x000003ff, 0xc0000000, D3DFMT_A2B10G10R10 },
199  { 32, 0x000003ff, 0x000ffc00, 0x3ff00000, 0xc0000000, D3DFMT_A2R10G10B10 },
200  { 32, 0x0000ffff, 0xffff0000, 0x00000000, 0x00000000, D3DFMT_G16R16 },
201  { 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000, D3DFMT_A8B8G8R8 },
202  { 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000, D3DFMT_X8B8G8R8 },
203 };
204 
205 static D3DFORMAT dds_rgb_to_d3dformat(const struct dds_pixel_format *pixel_format)
206 {
207  unsigned int i;
208 
209  for (i = 0; i < ARRAY_SIZE(rgb_pixel_formats); i++)
210  {
211  if (rgb_pixel_formats[i].bpp == pixel_format->bpp
212  && rgb_pixel_formats[i].rmask == pixel_format->rmask
213  && rgb_pixel_formats[i].gmask == pixel_format->gmask
214  && rgb_pixel_formats[i].bmask == pixel_format->bmask)
215  {
216  if ((pixel_format->flags & DDS_PF_ALPHA) && rgb_pixel_formats[i].amask == pixel_format->amask)
217  return rgb_pixel_formats[i].format;
218  if (rgb_pixel_formats[i].amask == 0)
219  return rgb_pixel_formats[i].format;
220  }
221  }
222 
223  WARN("Unknown RGB pixel format (%#x, %#x, %#x, %#x)\n",
224  pixel_format->rmask, pixel_format->gmask, pixel_format->bmask, pixel_format->amask);
225  return D3DFMT_UNKNOWN;
226 }
227 
228 static D3DFORMAT dds_luminance_to_d3dformat(const struct dds_pixel_format *pixel_format)
229 {
230  if (pixel_format->bpp == 8)
231  {
232  if (pixel_format->rmask == 0xff)
233  return D3DFMT_L8;
234  if ((pixel_format->flags & DDS_PF_ALPHA) && pixel_format->rmask == 0x0f && pixel_format->amask == 0xf0)
235  return D3DFMT_A4L4;
236  }
237  if (pixel_format->bpp == 16)
238  {
239  if (pixel_format->rmask == 0xffff)
240  return D3DFMT_L16;
241  if ((pixel_format->flags & DDS_PF_ALPHA) && pixel_format->rmask == 0x00ff && pixel_format->amask == 0xff00)
242  return D3DFMT_A8L8;
243  }
244 
245  WARN("Unknown luminance pixel format (bpp %u, l %#x, a %#x)\n",
246  pixel_format->bpp, pixel_format->rmask, pixel_format->amask);
247  return D3DFMT_UNKNOWN;
248 }
249 
250 static D3DFORMAT dds_alpha_to_d3dformat(const struct dds_pixel_format *pixel_format)
251 {
252  if (pixel_format->bpp == 8 && pixel_format->amask == 0xff)
253  return D3DFMT_A8;
254 
255  WARN("Unknown Alpha pixel format (%u, %#x)\n", pixel_format->bpp, pixel_format->rmask);
256  return D3DFMT_UNKNOWN;
257 }
258 
259 static D3DFORMAT dds_bump_to_d3dformat(const struct dds_pixel_format *pixel_format)
260 {
261  if (pixel_format->bpp == 16 && pixel_format->rmask == 0x00ff && pixel_format->gmask == 0xff00)
262  return D3DFMT_V8U8;
263  if (pixel_format->bpp == 32 && pixel_format->rmask == 0x0000ffff && pixel_format->gmask == 0xffff0000)
264  return D3DFMT_V16U16;
265 
266  WARN("Unknown bump pixel format (%u, %#x, %#x, %#x, %#x)\n", pixel_format->bpp,
267  pixel_format->rmask, pixel_format->gmask, pixel_format->bmask, pixel_format->amask);
268  return D3DFMT_UNKNOWN;
269 }
270 
272 {
273  if (pixel_format->bpp == 32 && pixel_format->rmask == 0x000000ff && pixel_format->gmask == 0x0000ff00
274  && pixel_format->bmask == 0x00ff0000)
275  return D3DFMT_X8L8V8U8;
276 
277  WARN("Unknown bump pixel format (%u, %#x, %#x, %#x, %#x)\n", pixel_format->bpp,
278  pixel_format->rmask, pixel_format->gmask, pixel_format->bmask, pixel_format->amask);
279  return D3DFMT_UNKNOWN;
280 }
281 
282 static D3DFORMAT dds_pixel_format_to_d3dformat(const struct dds_pixel_format *pixel_format)
283 {
284  TRACE("pixel_format: size %u, flags %#x, fourcc %#x, bpp %u.\n", pixel_format->size,
285  pixel_format->flags, pixel_format->fourcc, pixel_format->bpp);
286  TRACE("rmask %#x, gmask %#x, bmask %#x, amask %#x.\n", pixel_format->rmask, pixel_format->gmask,
287  pixel_format->bmask, pixel_format->amask);
288 
289  if (pixel_format->flags & DDS_PF_FOURCC)
290  return dds_fourcc_to_d3dformat(pixel_format->fourcc);
291  if (pixel_format->flags & DDS_PF_RGB)
292  return dds_rgb_to_d3dformat(pixel_format);
293  if (pixel_format->flags & DDS_PF_LUMINANCE)
294  return dds_luminance_to_d3dformat(pixel_format);
295  if (pixel_format->flags & DDS_PF_ALPHA_ONLY)
296  return dds_alpha_to_d3dformat(pixel_format);
297  if (pixel_format->flags & DDS_PF_BUMPDUDV)
298  return dds_bump_to_d3dformat(pixel_format);
299  if (pixel_format->flags & DDS_PF_BUMPLUMINANCE)
300  return dds_bump_luminance_to_d3dformat(pixel_format);
301 
302  WARN("Unknown pixel format (flags %#x, fourcc %#x, bpp %u, r %#x, g %#x, b %#x, a %#x)\n",
303  pixel_format->flags, pixel_format->fourcc, pixel_format->bpp,
304  pixel_format->rmask, pixel_format->gmask, pixel_format->bmask, pixel_format->amask);
305  return D3DFMT_UNKNOWN;
306 }
307 
309 {
310  unsigned int i;
311 
312  memset(pixel_format, 0, sizeof(*pixel_format));
313 
314  pixel_format->size = sizeof(*pixel_format);
315 
316  for (i = 0; i < ARRAY_SIZE(rgb_pixel_formats); i++)
317  {
318  if (rgb_pixel_formats[i].format == d3dformat)
319  {
320  pixel_format->flags |= DDS_PF_RGB;
321  pixel_format->bpp = rgb_pixel_formats[i].bpp;
322  pixel_format->rmask = rgb_pixel_formats[i].rmask;
323  pixel_format->gmask = rgb_pixel_formats[i].gmask;
324  pixel_format->bmask = rgb_pixel_formats[i].bmask;
325  pixel_format->amask = rgb_pixel_formats[i].amask;
326  if (pixel_format->amask) pixel_format->flags |= DDS_PF_ALPHA;
327  return D3D_OK;
328  }
329  }
330 
331  /* Reuse dds_fourcc_to_d3dformat as D3DFORMAT and FOURCC are DWORD with same values */
332  if (dds_fourcc_to_d3dformat(d3dformat) != D3DFMT_UNKNOWN)
333  {
334  pixel_format->flags |= DDS_PF_FOURCC;
335  pixel_format->fourcc = d3dformat;
336  return D3D_OK;
337  }
338 
339  WARN("Unknown pixel format %#x\n", d3dformat);
340  return E_NOTIMPL;
341 }
342 
344  UINT *pitch, UINT *size)
345 {
346  const struct pixel_format_desc *format_desc = get_format_info(format);
347  if (format_desc->type == FORMAT_UNKNOWN)
348  return E_NOTIMPL;
349 
350  if (format_desc->block_width != 1 || format_desc->block_height != 1)
351  {
352  *pitch = format_desc->block_byte_count
353  * max(1, (width + format_desc->block_width - 1) / format_desc->block_width);
354  *size = *pitch
355  * max(1, (height + format_desc->block_height - 1) / format_desc->block_height);
356  }
357  else
358  {
359  *pitch = width * format_desc->bytes_per_pixel;
360  *size = *pitch * height;
361  }
362 
363  return D3D_OK;
364 }
365 
367  UINT miplevels, UINT faces)
368 {
369  UINT i, file_size = 0;
370 
371  for (i = 0; i < miplevels; i++)
372  {
373  UINT pitch, size = 0;
374  calculate_dds_surface_size(format, width, height, &pitch, &size);
375  size *= depth;
376  file_size += size;
377  width = max(1, width / 2);
378  height = max(1, height / 2);
379  depth = max(1, depth / 2);
380  }
381 
382  file_size *= faces;
383  file_size += sizeof(struct dds_header);
384  return file_size;
385 }
386 
387 /************************************************************
388 * get_image_info_from_dds
389 *
390 * Fills a D3DXIMAGE_INFO structure with information
391 * about a DDS file stored in the memory.
392 *
393 * PARAMS
394 * buffer [I] pointer to DDS data
395 * length [I] size of DDS data
396 * info [O] pointer to D3DXIMAGE_INFO structure
397 *
398 * RETURNS
399 * Success: D3D_OK
400 * Failure: D3DXERR_INVALIDDATA
401 *
402 */
404 {
405  UINT faces = 1;
406  UINT expected_length;
407  const struct dds_header *header = buffer;
408 
409  if (length < sizeof(*header) || !info)
410  return D3DXERR_INVALIDDATA;
411 
412  if (header->pixel_format.size != sizeof(header->pixel_format))
413  return D3DXERR_INVALIDDATA;
414 
415  info->Width = header->width;
416  info->Height = header->height;
417  info->Depth = 1;
418  info->MipLevels = header->miplevels ? header->miplevels : 1;
419 
421  if (info->Format == D3DFMT_UNKNOWN)
422  return D3DXERR_INVALIDDATA;
423 
424  TRACE("Pixel format is %#x\n", info->Format);
425 
426  if (header->caps2 & DDS_CAPS2_VOLUME)
427  {
428  info->Depth = header->depth;
430  }
431  else if (header->caps2 & DDS_CAPS2_CUBEMAP)
432  {
433  DWORD face;
434  faces = 0;
435  for (face = DDS_CAPS2_CUBEMAP_POSITIVEX; face <= DDS_CAPS2_CUBEMAP_NEGATIVEZ; face <<= 1)
436  {
437  if (header->caps2 & face)
438  faces++;
439  }
441  }
442  else
443  {
445  }
446 
447  expected_length = calculate_dds_file_size(info->Format, info->Width, info->Height, info->Depth,
448  info->MipLevels, faces);
449  if (length < expected_length)
450  {
451  WARN("File is too short %u, expected at least %u bytes\n", length, expected_length);
452  return D3DXERR_INVALIDDATA;
453  }
454 
456  return D3D_OK;
457 }
458 
459 static HRESULT load_surface_from_dds(IDirect3DSurface9 *dst_surface, const PALETTEENTRY *dst_palette,
460  const RECT *dst_rect, const void *src_data, const RECT *src_rect, DWORD filter, D3DCOLOR color_key,
461  const D3DXIMAGE_INFO *src_info)
462 {
463  UINT size;
464  UINT src_pitch;
465  const struct dds_header *header = src_data;
466  const BYTE *pixels = (BYTE *)(header + 1);
467 
468  if (src_info->ResourceType != D3DRTYPE_TEXTURE)
469  return D3DXERR_INVALIDDATA;
470 
471  if (FAILED(calculate_dds_surface_size(src_info->Format, src_info->Width, src_info->Height, &src_pitch, &size)))
472  return E_NOTIMPL;
473 
474  return D3DXLoadSurfaceFromMemory(dst_surface, dst_palette, dst_rect, pixels, src_info->Format,
475  src_pitch, NULL, src_rect, filter, color_key);
476 }
477 
478 static HRESULT save_dds_surface_to_memory(ID3DXBuffer **dst_buffer, IDirect3DSurface9 *src_surface, const RECT *src_rect)
479 {
480  HRESULT hr;
481  UINT dst_pitch, surface_size, file_size;
482  D3DSURFACE_DESC src_desc;
483  D3DLOCKED_RECT locked_rect;
485  struct dds_header *header;
486  BYTE *pixels;
487  struct volume volume;
488  const struct pixel_format_desc *pixel_format;
489 
490  if (src_rect)
491  {
492  FIXME("Saving a part of a surface to a DDS file is not implemented yet\n");
493  return E_NOTIMPL;
494  }
495 
496  hr = IDirect3DSurface9_GetDesc(src_surface, &src_desc);
497  if (FAILED(hr)) return hr;
498 
499  pixel_format = get_format_info(src_desc.Format);
500  if (pixel_format->type == FORMAT_UNKNOWN) return E_NOTIMPL;
501 
502  file_size = calculate_dds_file_size(src_desc.Format, src_desc.Width, src_desc.Height, 1, 1, 1);
503 
504  hr = calculate_dds_surface_size(src_desc.Format, src_desc.Width, src_desc.Height, &dst_pitch, &surface_size);
505  if (FAILED(hr)) return hr;
506 
507  hr = D3DXCreateBuffer(file_size, &buffer);
508  if (FAILED(hr)) return hr;
509 
510  header = ID3DXBuffer_GetBufferPointer(buffer);
511  pixels = (BYTE *)(header + 1);
512 
513  memset(header, 0, sizeof(*header));
514  header->signature = MAKEFOURCC('D','D','S',' ');
515  /* The signature is not really part of the DDS header */
516  header->size = sizeof(*header) - FIELD_OFFSET(struct dds_header, size);
518  header->height = src_desc.Height;
519  header->width = src_desc.Width;
520  header->caps = DDS_CAPS_TEXTURE;
521  hr = d3dformat_to_dds_pixel_format(&header->pixel_format, src_desc.Format);
522  if (FAILED(hr))
523  {
524  ID3DXBuffer_Release(buffer);
525  return hr;
526  }
527 
528  hr = IDirect3DSurface9_LockRect(src_surface, &locked_rect, NULL, D3DLOCK_READONLY);
529  if (FAILED(hr))
530  {
531  ID3DXBuffer_Release(buffer);
532  return hr;
533  }
534 
535  volume.width = src_desc.Width;
536  volume.height = src_desc.Height;
537  volume.depth = 1;
538  copy_pixels(locked_rect.pBits, locked_rect.Pitch, 0, pixels, dst_pitch, 0,
539  &volume, pixel_format);
540 
541  IDirect3DSurface9_UnlockRect(src_surface);
542 
543  *dst_buffer = buffer;
544  return D3D_OK;
545 }
546 
547 static HRESULT get_surface(D3DRESOURCETYPE type, struct IDirect3DBaseTexture9 *tex,
548  int face, UINT level, struct IDirect3DSurface9 **surf)
549 {
550  switch (type)
551  {
552  case D3DRTYPE_TEXTURE:
553  return IDirect3DTexture9_GetSurfaceLevel((IDirect3DTexture9*) tex, level, surf);
555  return IDirect3DCubeTexture9_GetCubeMapSurface((IDirect3DCubeTexture9*) tex, face, level, surf);
556  default:
557  ERR("Unexpected texture type\n");
558  return E_NOTIMPL;
559  }
560 }
561 
562 HRESULT save_dds_texture_to_memory(ID3DXBuffer **dst_buffer, IDirect3DBaseTexture9 *src_texture, const PALETTEENTRY *src_palette)
563 {
564  HRESULT hr;
566  UINT mip_levels;
567  IDirect3DSurface9 *surface;
568 
569  type = IDirect3DBaseTexture9_GetType(src_texture);
570 
571  if ((type != D3DRTYPE_TEXTURE) && (type != D3DRTYPE_CUBETEXTURE) && (type != D3DRTYPE_VOLUMETEXTURE))
572  return D3DERR_INVALIDCALL;
573 
574  if (type == D3DRTYPE_CUBETEXTURE)
575  {
576  FIXME("Cube texture not supported yet\n");
577  return E_NOTIMPL;
578  }
579  else if (type == D3DRTYPE_VOLUMETEXTURE)
580  {
581  FIXME("Volume texture not supported yet\n");
582  return E_NOTIMPL;
583  }
584 
585  mip_levels = IDirect3DTexture9_GetLevelCount(src_texture);
586 
587  if (mip_levels > 1)
588  {
589  FIXME("Mipmap not supported yet\n");
590  return E_NOTIMPL;
591  }
592 
593  if (src_palette)
594  {
595  FIXME("Saving surfaces with palettized pixel formats not implemented yet\n");
596  return E_NOTIMPL;
597  }
598 
599  hr = get_surface(type, src_texture, D3DCUBEMAP_FACE_POSITIVE_X, 0, &surface);
600 
601  if (SUCCEEDED(hr))
602  {
603  hr = save_dds_surface_to_memory(dst_buffer, surface, NULL);
604  IDirect3DSurface9_Release(surface);
605  }
606 
607  return hr;
608 }
609 HRESULT load_volume_from_dds(IDirect3DVolume9 *dst_volume, const PALETTEENTRY *dst_palette,
610  const D3DBOX *dst_box, const void *src_data, const D3DBOX *src_box, DWORD filter, D3DCOLOR color_key,
611  const D3DXIMAGE_INFO *src_info)
612 {
613  UINT row_pitch, slice_pitch;
614  const struct dds_header *header = src_data;
615  const BYTE *pixels = (BYTE *)(header + 1);
616 
617  if (src_info->ResourceType != D3DRTYPE_VOLUMETEXTURE)
618  return D3DXERR_INVALIDDATA;
619 
620  if (FAILED(calculate_dds_surface_size(src_info->Format, src_info->Width, src_info->Height, &row_pitch, &slice_pitch)))
621  return E_NOTIMPL;
622 
623  return D3DXLoadVolumeFromMemory(dst_volume, dst_palette, dst_box, pixels, src_info->Format,
624  row_pitch, slice_pitch, NULL, src_box, filter, color_key);
625 }
626 
627 HRESULT load_texture_from_dds(IDirect3DTexture9 *texture, const void *src_data, const PALETTEENTRY *palette,
628  DWORD filter, D3DCOLOR color_key, const D3DXIMAGE_INFO *src_info, unsigned int skip_levels,
629  unsigned int *loaded_miplevels)
630 {
631  HRESULT hr;
632  RECT src_rect;
633  UINT src_pitch;
634  UINT mip_level;
635  UINT mip_levels;
636  UINT mip_level_size;
637  UINT width, height;
638  IDirect3DSurface9 *surface;
639  const struct dds_header *header = src_data;
640  const BYTE *pixels = (BYTE *)(header + 1);
641 
642  /* Loading a cube texture as a simple texture is also supported
643  * (only first face texture is taken). Same with volume textures. */
644  if ((src_info->ResourceType != D3DRTYPE_TEXTURE)
645  && (src_info->ResourceType != D3DRTYPE_CUBETEXTURE)
646  && (src_info->ResourceType != D3DRTYPE_VOLUMETEXTURE))
647  {
648  WARN("Trying to load a %u resource as a 2D texture, returning failure.\n", src_info->ResourceType);
649  return D3DXERR_INVALIDDATA;
650  }
651 
652  width = src_info->Width;
653  height = src_info->Height;
654  mip_levels = min(src_info->MipLevels, IDirect3DTexture9_GetLevelCount(texture));
655  if (src_info->ResourceType == D3DRTYPE_VOLUMETEXTURE)
656  mip_levels = 1;
657  for (mip_level = 0; mip_level < mip_levels + skip_levels; ++mip_level)
658  {
659  hr = calculate_dds_surface_size(src_info->Format, width, height, &src_pitch, &mip_level_size);
660  if (FAILED(hr)) return hr;
661 
662  if (mip_level >= skip_levels)
663  {
664  SetRect(&src_rect, 0, 0, width, height);
665 
666  IDirect3DTexture9_GetSurfaceLevel(texture, mip_level - skip_levels, &surface);
667  hr = D3DXLoadSurfaceFromMemory(surface, palette, NULL, pixels, src_info->Format, src_pitch,
668  NULL, &src_rect, filter, color_key);
669  IDirect3DSurface9_Release(surface);
670  if (FAILED(hr))
671  return hr;
672  }
673 
674  pixels += mip_level_size;
675  width = max(1, width / 2);
676  height = max(1, height / 2);
677  }
678 
679  *loaded_miplevels = mip_levels - skip_levels;
680 
681  return D3D_OK;
682 }
683 
684 HRESULT load_cube_texture_from_dds(IDirect3DCubeTexture9 *cube_texture, const void *src_data,
685  const PALETTEENTRY *palette, DWORD filter, DWORD color_key, const D3DXIMAGE_INFO *src_info)
686 {
687  HRESULT hr;
688  int face;
689  UINT mip_level;
690  UINT size;
691  RECT src_rect;
692  UINT src_pitch;
693  UINT mip_levels;
694  UINT mip_level_size;
695  IDirect3DSurface9 *surface;
696  const struct dds_header *header = src_data;
697  const BYTE *pixels = (BYTE *)(header + 1);
698 
699  if (src_info->ResourceType != D3DRTYPE_CUBETEXTURE)
700  return D3DXERR_INVALIDDATA;
701 
703  {
704  WARN("Only full cubemaps are supported\n");
705  return D3DXERR_INVALIDDATA;
706  }
707 
708  mip_levels = min(src_info->MipLevels, IDirect3DCubeTexture9_GetLevelCount(cube_texture));
709  for (face = D3DCUBEMAP_FACE_POSITIVE_X; face <= D3DCUBEMAP_FACE_NEGATIVE_Z; face++)
710  {
711  size = src_info->Width;
712  for (mip_level = 0; mip_level < src_info->MipLevels; mip_level++)
713  {
714  hr = calculate_dds_surface_size(src_info->Format, size, size, &src_pitch, &mip_level_size);
715  if (FAILED(hr)) return hr;
716 
717  /* if texture has fewer mip levels than DDS file, skip excessive mip levels */
718  if (mip_level < mip_levels)
719  {
720  SetRect(&src_rect, 0, 0, size, size);
721 
722  IDirect3DCubeTexture9_GetCubeMapSurface(cube_texture, face, mip_level, &surface);
723  hr = D3DXLoadSurfaceFromMemory(surface, palette, NULL, pixels, src_info->Format, src_pitch,
724  NULL, &src_rect, filter, color_key);
725  IDirect3DSurface9_Release(surface);
726  if (FAILED(hr)) return hr;
727  }
728 
729  pixels += mip_level_size;
730  size = max(1, size / 2);
731  }
732  }
733 
734  return D3D_OK;
735 }
736 
737 HRESULT load_volume_texture_from_dds(IDirect3DVolumeTexture9 *volume_texture, const void *src_data,
738  const PALETTEENTRY *palette, DWORD filter, DWORD color_key, const D3DXIMAGE_INFO *src_info)
739 {
740  HRESULT hr;
741  UINT mip_level;
742  UINT mip_levels;
743  UINT src_slice_pitch;
744  UINT src_row_pitch;
745  D3DBOX src_box;
747  IDirect3DVolume9 *volume;
748  const struct dds_header *header = src_data;
749  const BYTE *pixels = (BYTE *)(header + 1);
750 
751  if (src_info->ResourceType != D3DRTYPE_VOLUMETEXTURE)
752  return D3DXERR_INVALIDDATA;
753 
754  width = src_info->Width;
755  height = src_info->Height;
756  depth = src_info->Depth;
757  mip_levels = min(src_info->MipLevels, IDirect3DVolumeTexture9_GetLevelCount(volume_texture));
758 
759  for (mip_level = 0; mip_level < mip_levels; mip_level++)
760  {
761  hr = calculate_dds_surface_size(src_info->Format, width, height, &src_row_pitch, &src_slice_pitch);
762  if (FAILED(hr)) return hr;
763 
764  hr = IDirect3DVolumeTexture9_GetVolumeLevel(volume_texture, mip_level, &volume);
765  if (FAILED(hr)) return hr;
766 
767  src_box.Left = 0;
768  src_box.Top = 0;
769  src_box.Right = width;
770  src_box.Bottom = height;
771  src_box.Front = 0;
772  src_box.Back = depth;
773 
774  hr = D3DXLoadVolumeFromMemory(volume, palette, NULL, pixels, src_info->Format,
775  src_row_pitch, src_slice_pitch, NULL, &src_box, filter, color_key);
776 
777  IDirect3DVolume9_Release(volume);
778  if (FAILED(hr)) return hr;
779 
780  pixels += depth * src_slice_pitch;
781  width = max(1, width / 2);
782  height = max(1, height / 2);
783  depth = max(1, depth / 2);
784  }
785 
786  return D3D_OK;
787 }
788 
790 {
791  ULONG header_size;
792  ULONG count = 0;
793  ULONG offset;
795  BYTE *new_data;
796  UINT new_size;
797 
798  if ((*size < 4) || (*size < (header_size = *(ULONG*)*data)))
799  return FALSE;
800 
801  if ((header_size == sizeof(BITMAPINFOHEADER)) ||
802  (header_size == sizeof(BITMAPV4HEADER)) ||
803  (header_size == sizeof(BITMAPV5HEADER)) ||
804  (header_size == 64 /* sizeof(BITMAPCOREHEADER2) */))
805  {
806  /* All structures begin with the same memory layout as BITMAPINFOHEADER */
807  BITMAPINFOHEADER *info_header = (BITMAPINFOHEADER*)*data;
808  count = info_header->biClrUsed;
809 
810  if (!count && info_header->biBitCount <= 8)
811  count = 1 << info_header->biBitCount;
812 
813  offset = sizeof(BITMAPFILEHEADER) + header_size + sizeof(RGBQUAD) * count;
814 
815  /* For BITMAPINFOHEADER with BI_BITFIELDS compression, there are 3 additional color masks after header */
816  if ((info_header->biSize == sizeof(BITMAPINFOHEADER)) && (info_header->biCompression == BI_BITFIELDS))
817  offset += 3 * sizeof(DWORD);
818  }
819  else if (header_size == sizeof(BITMAPCOREHEADER))
820  {
821  BITMAPCOREHEADER *core_header = (BITMAPCOREHEADER*)*data;
822 
823  if (core_header->bcBitCount <= 8)
824  count = 1 << core_header->bcBitCount;
825 
826  offset = sizeof(BITMAPFILEHEADER) + header_size + sizeof(RGBTRIPLE) * count;
827  }
828  else
829  {
830  return FALSE;
831  }
832 
833  TRACE("Converting DIB file to BMP\n");
834 
835  new_size = *size + sizeof(BITMAPFILEHEADER);
836  new_data = HeapAlloc(GetProcessHeap(), 0, new_size);
837  CopyMemory(new_data + sizeof(BITMAPFILEHEADER), *data, *size);
838 
839  /* Add BMP header */
840  header = (BITMAPFILEHEADER*)new_data;
841  header->bfType = 0x4d42; /* BM */
842  header->bfSize = new_size;
843  header->bfReserved1 = 0;
844  header->bfReserved2 = 0;
845  header->bfOffBits = offset;
846 
847  /* Update input data */
848  *data = new_data;
849  *size = new_size;
850 
851  return TRUE;
852 }
853 
854 /************************************************************
855  * D3DXGetImageInfoFromFileInMemory
856  *
857  * Fills a D3DXIMAGE_INFO structure with info about an image
858  *
859  * PARAMS
860  * data [I] pointer to the image file data
861  * datasize [I] size of the passed data
862  * info [O] pointer to the destination structure
863  *
864  * RETURNS
865  * Success: D3D_OK, if info is not NULL and data and datasize make up a valid image file or
866  * if info is NULL and data and datasize are not NULL
867  * Failure: D3DXERR_INVALIDDATA, if data is no valid image file and datasize and info are not NULL
868  * D3DERR_INVALIDCALL, if data is NULL or
869  * if datasize is 0
870  *
871  * NOTES
872  * datasize may be bigger than the actual file size
873  *
874  */
876 {
878  IWICBitmapDecoder *decoder = NULL;
880  HRESULT hr;
881  HRESULT initresult;
882  BOOL dib;
883 
884  TRACE("(%p, %d, %p)\n", data, datasize, info);
885 
886  if (!data || !datasize)
887  return D3DERR_INVALIDCALL;
888 
889  if (!info)
890  return D3D_OK;
891 
892  if ((datasize >= 4) && !strncmp(data, "DDS ", 4)) {
893  TRACE("File type is DDS\n");
894  return get_image_info_from_dds(data, datasize, info);
895  }
896 
897  /* In case of DIB file, convert it to BMP */
898  dib = convert_dib_to_bmp((void**)&data, &datasize);
899 
901 
902  hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory);
903 
904  if (SUCCEEDED(hr)) {
905  IWICImagingFactory_CreateStream(factory, &stream);
906  IWICStream_InitializeFromMemory(stream, (BYTE*)data, datasize);
907  hr = IWICImagingFactory_CreateDecoderFromStream(factory, (IStream*)stream, NULL, 0, &decoder);
908  IWICStream_Release(stream);
909  IWICImagingFactory_Release(factory);
910  }
911 
912  if (FAILED(hr)) {
913  if ((datasize >= 2) && (!strncmp(data, "P3", 2) || !strncmp(data, "P6", 2)))
914  FIXME("File type PPM is not supported yet\n");
915  else if ((datasize >= 10) && !strncmp(data, "#?RADIANCE", 10))
916  FIXME("File type HDR is not supported yet\n");
917  else if ((datasize >= 2) && (!strncmp(data, "PF", 2) || !strncmp(data, "Pf", 2)))
918  FIXME("File type PFM is not supported yet\n");
919  }
920 
921  if (SUCCEEDED(hr)) {
922  GUID container_format;
923  UINT frame_count;
924 
925  hr = IWICBitmapDecoder_GetContainerFormat(decoder, &container_format);
926  if (SUCCEEDED(hr)) {
927  if (IsEqualGUID(&container_format, &GUID_ContainerFormatBmp)) {
928  if (dib) {
929  TRACE("File type is DIB\n");
931  } else {
932  TRACE("File type is BMP\n");
934  }
935  } else if (IsEqualGUID(&container_format, &GUID_ContainerFormatPng)) {
936  TRACE("File type is PNG\n");
938  } else if(IsEqualGUID(&container_format, &GUID_ContainerFormatJpeg)) {
939  TRACE("File type is JPG\n");
941  } else if(IsEqualGUID(&container_format, &GUID_WineContainerFormatTga)) {
942  TRACE("File type is TGA\n");
944  } else {
945  WARN("Unsupported image file format %s\n", debugstr_guid(&container_format));
946  hr = D3DXERR_INVALIDDATA;
947  }
948  }
949 
950  if (SUCCEEDED(hr))
951  hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count);
952  if (SUCCEEDED(hr) && !frame_count)
953  hr = D3DXERR_INVALIDDATA;
954 
955  if (SUCCEEDED(hr)) {
956  IWICBitmapFrameDecode *frame = NULL;
957 
958  hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
959 
960  if (SUCCEEDED(hr))
961  hr = IWICBitmapFrameDecode_GetSize(frame, &info->Width, &info->Height);
962 
963  if (SUCCEEDED(hr)) {
965 
966  hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &pixel_format);
967  if (SUCCEEDED(hr)) {
968  info->Format = wic_guid_to_d3dformat(&pixel_format);
969  if (info->Format == D3DFMT_UNKNOWN) {
970  WARN("Unsupported pixel format %s\n", debugstr_guid(&pixel_format));
971  hr = D3DXERR_INVALIDDATA;
972  }
973  }
974  }
975 
976  /* For 32 bpp BMP, windowscodecs.dll never returns a format with alpha while
977  * d3dx9_xx.dll returns one if at least 1 pixel has a non zero alpha component */
978  if (SUCCEEDED(hr) && (info->Format == D3DFMT_X8R8G8B8) && (info->ImageFileFormat == D3DXIFF_BMP)) {
979  DWORD size = sizeof(DWORD) * info->Width * info->Height;
981  hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, sizeof(DWORD) * info->Width, size, buffer);
982  if (SUCCEEDED(hr)) {
983  DWORD i;
984  for (i = 0; i < info->Width * info->Height; i++) {
985  if (buffer[i*4+3]) {
986  info->Format = D3DFMT_A8R8G8B8;
987  break;
988  }
989  }
990  }
992  }
993 
994  if (frame)
995  IWICBitmapFrameDecode_Release(frame);
996 
997  info->Depth = 1;
998  info->MipLevels = 1;
1000  }
1001  }
1002 
1003  if (decoder)
1004  IWICBitmapDecoder_Release(decoder);
1005 
1006  if (SUCCEEDED(initresult))
1007  CoUninitialize();
1008 
1009  if (dib)
1010  HeapFree(GetProcessHeap(), 0, (void*)data);
1011 
1012  if (FAILED(hr)) {
1013  TRACE("Invalid or unsupported image file\n");
1014  return D3DXERR_INVALIDDATA;
1015  }
1016 
1017  return D3D_OK;
1018 }
1019 
1020 /************************************************************
1021  * D3DXGetImageInfoFromFile
1022  *
1023  * RETURNS
1024  * Success: D3D_OK, if we successfully load a valid image file or
1025  * if we successfully load a file which is no valid image and info is NULL
1026  * Failure: D3DXERR_INVALIDDATA, if we fail to load file or
1027  * if file is not a valid image file and info is not NULL
1028  * D3DERR_INVALIDCALL, if file is NULL
1029  *
1030  */
1032 {
1033  WCHAR *widename;
1034  HRESULT hr;
1035  int strlength;
1036 
1037  TRACE("file %s, info %p.\n", debugstr_a(file), info);
1038 
1039  if( !file ) return D3DERR_INVALIDCALL;
1040 
1041  strlength = MultiByteToWideChar(CP_ACP, 0, file, -1, NULL, 0);
1042  widename = HeapAlloc(GetProcessHeap(), 0, strlength * sizeof(*widename));
1043  MultiByteToWideChar(CP_ACP, 0, file, -1, widename, strlength);
1044 
1045  hr = D3DXGetImageInfoFromFileW(widename, info);
1046  HeapFree(GetProcessHeap(), 0, widename);
1047 
1048  return hr;
1049 }
1050 
1052 {
1053  void *buffer;
1054  HRESULT hr;
1055  DWORD size;
1056 
1057  TRACE("file %s, info %p.\n", debugstr_w(file), info);
1058 
1059  if (!file)
1060  return D3DERR_INVALIDCALL;
1061 
1062  if (FAILED(map_view_of_file(file, &buffer, &size)))
1063  return D3DXERR_INVALIDDATA;
1064 
1065  hr = D3DXGetImageInfoFromFileInMemory(buffer, size, info);
1066  UnmapViewOfFile(buffer);
1067 
1068  return hr;
1069 }
1070 
1071 /************************************************************
1072  * D3DXGetImageInfoFromResource
1073  *
1074  * RETURNS
1075  * Success: D3D_OK, if resource is a valid image file
1076  * Failure: D3DXERR_INVALIDDATA, if resource is no valid image file or NULL or
1077  * if we fail to load resource
1078  *
1079  */
1081 {
1082  HRSRC resinfo;
1083  void *buffer;
1084  DWORD size;
1085 
1086  TRACE("module %p, resource %s, info %p.\n", module, debugstr_a(resource), info);
1087 
1088  if (!(resinfo = FindResourceA(module, resource, (const char *)RT_RCDATA))
1089  /* Try loading the resource as bitmap data (which is in DIB format D3DXIFF_DIB) */
1090  && !(resinfo = FindResourceA(module, resource, (const char *)RT_BITMAP)))
1091  return D3DXERR_INVALIDDATA;
1092 
1093  if (FAILED(load_resource_into_memory(module, resinfo, &buffer, &size)))
1094  return D3DXERR_INVALIDDATA;
1095 
1096  return D3DXGetImageInfoFromFileInMemory(buffer, size, info);
1097 }
1098 
1100 {
1101  HRSRC resinfo;
1102  void *buffer;
1103  DWORD size;
1104 
1105  TRACE("module %p, resource %s, info %p.\n", module, debugstr_w(resource), info);
1106 
1107  if (!(resinfo = FindResourceW(module, resource, (const WCHAR *)RT_RCDATA))
1108  /* Try loading the resource as bitmap data (which is in DIB format D3DXIFF_DIB) */
1109  && !(resinfo = FindResourceW(module, resource, (const WCHAR *)RT_BITMAP)))
1110  return D3DXERR_INVALIDDATA;
1111 
1112  if (FAILED(load_resource_into_memory(module, resinfo, &buffer, &size)))
1113  return D3DXERR_INVALIDDATA;
1114 
1115  return D3DXGetImageInfoFromFileInMemory(buffer, size, info);
1116 }
1117 
1118 /************************************************************
1119  * D3DXLoadSurfaceFromFileInMemory
1120  *
1121  * Loads data from a given buffer into a surface and fills a given
1122  * D3DXIMAGE_INFO structure with info about the source data.
1123  *
1124  * PARAMS
1125  * pDestSurface [I] pointer to the surface
1126  * pDestPalette [I] palette to use
1127  * pDestRect [I] to be filled area of the surface
1128  * pSrcData [I] pointer to the source data
1129  * SrcDataSize [I] size of the source data in bytes
1130  * pSrcRect [I] area of the source data to load
1131  * dwFilter [I] filter to apply on stretching
1132  * Colorkey [I] colorkey
1133  * pSrcInfo [O] pointer to a D3DXIMAGE_INFO structure
1134  *
1135  * RETURNS
1136  * Success: D3D_OK
1137  * Failure: D3DERR_INVALIDCALL, if pDestSurface, pSrcData or SrcDataSize is NULL
1138  * D3DXERR_INVALIDDATA, if pSrcData is no valid image file
1139  *
1140  */
1141 HRESULT WINAPI D3DXLoadSurfaceFromFileInMemory(IDirect3DSurface9 *pDestSurface,
1142  const PALETTEENTRY *pDestPalette, const RECT *pDestRect, const void *pSrcData, UINT SrcDataSize,
1143  const RECT *pSrcRect, DWORD dwFilter, D3DCOLOR Colorkey, D3DXIMAGE_INFO *pSrcInfo)
1144 {
1145  D3DXIMAGE_INFO imginfo;
1146  HRESULT hr, com_init;
1147 
1149  IWICBitmapDecoder *decoder;
1150  IWICBitmapFrameDecode *bitmapframe;
1151  IWICStream *stream;
1152 
1153  const struct pixel_format_desc *formatdesc;
1154  WICRect wicrect;
1155  RECT rect;
1156 
1157  TRACE("dst_surface %p, dst_palette %p, dst_rect %s, src_data %p, src_data_size %u, "
1158  "src_rect %s, filter %#x, color_key 0x%08x, src_info %p.\n",
1159  pDestSurface, pDestPalette, wine_dbgstr_rect(pDestRect), pSrcData, SrcDataSize,
1160  wine_dbgstr_rect(pSrcRect), dwFilter, Colorkey, pSrcInfo);
1161 
1162  if (!pDestSurface || !pSrcData || !SrcDataSize)
1163  return D3DERR_INVALIDCALL;
1164 
1165  hr = D3DXGetImageInfoFromFileInMemory(pSrcData, SrcDataSize, &imginfo);
1166 
1167  if (FAILED(hr))
1168  return hr;
1169 
1170  if (pSrcRect)
1171  {
1172  wicrect.X = pSrcRect->left;
1173  wicrect.Y = pSrcRect->top;
1174  wicrect.Width = pSrcRect->right - pSrcRect->left;
1175  wicrect.Height = pSrcRect->bottom - pSrcRect->top;
1176  }
1177  else
1178  {
1179  wicrect.X = 0;
1180  wicrect.Y = 0;
1181  wicrect.Width = imginfo.Width;
1182  wicrect.Height = imginfo.Height;
1183  }
1184 
1185  SetRect(&rect, 0, 0, wicrect.Width, wicrect.Height);
1186 
1187  if (imginfo.ImageFileFormat == D3DXIFF_DDS)
1188  {
1189  hr = load_surface_from_dds(pDestSurface, pDestPalette, pDestRect, pSrcData, &rect,
1190  dwFilter, Colorkey, &imginfo);
1191  if (SUCCEEDED(hr) && pSrcInfo)
1192  *pSrcInfo = imginfo;
1193  return hr;
1194  }
1195 
1196  if (imginfo.ImageFileFormat == D3DXIFF_DIB)
1197  convert_dib_to_bmp((void**)&pSrcData, &SrcDataSize);
1198 
1200 
1201  if (FAILED(CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory)))
1202  goto cleanup_err;
1203 
1204  if (FAILED(IWICImagingFactory_CreateStream(factory, &stream)))
1205  {
1206  IWICImagingFactory_Release(factory);
1207  factory = NULL;
1208  goto cleanup_err;
1209  }
1210 
1211  IWICStream_InitializeFromMemory(stream, (BYTE*)pSrcData, SrcDataSize);
1212 
1213  hr = IWICImagingFactory_CreateDecoderFromStream(factory, (IStream*)stream, NULL, 0, &decoder);
1214 
1215  IWICStream_Release(stream);
1216 
1217  if (FAILED(hr))
1218  goto cleanup_err;
1219 
1220  hr = IWICBitmapDecoder_GetFrame(decoder, 0, &bitmapframe);
1221 
1222  if (FAILED(hr))
1223  goto cleanup_bmp;
1224 
1225  formatdesc = get_format_info(imginfo.Format);
1226 
1227  if (formatdesc->type == FORMAT_UNKNOWN)
1228  {
1229  FIXME("Unsupported pixel format\n");
1230  hr = D3DXERR_INVALIDDATA;
1231  }
1232  else
1233  {
1234  BYTE *buffer;
1235  DWORD pitch;
1237  WICColor *colors = NULL;
1238 
1239  pitch = formatdesc->bytes_per_pixel * wicrect.Width;
1240  buffer = HeapAlloc(GetProcessHeap(), 0, pitch * wicrect.Height);
1241 
1242  hr = IWICBitmapFrameDecode_CopyPixels(bitmapframe, &wicrect, pitch,
1243  pitch * wicrect.Height, buffer);
1244 
1245  if (SUCCEEDED(hr) && (formatdesc->type == FORMAT_INDEX))
1246  {
1247  IWICPalette *wic_palette = NULL;
1248  UINT nb_colors;
1249 
1250  hr = IWICImagingFactory_CreatePalette(factory, &wic_palette);
1251  if (SUCCEEDED(hr))
1252  hr = IWICBitmapFrameDecode_CopyPalette(bitmapframe, wic_palette);
1253  if (SUCCEEDED(hr))
1254  hr = IWICPalette_GetColorCount(wic_palette, &nb_colors);
1255  if (SUCCEEDED(hr))
1256  {
1257  colors = HeapAlloc(GetProcessHeap(), 0, nb_colors * sizeof(colors[0]));
1258  palette = HeapAlloc(GetProcessHeap(), 0, nb_colors * sizeof(palette[0]));
1259  if (!colors || !palette)
1260  hr = E_OUTOFMEMORY;
1261  }
1262  if (SUCCEEDED(hr))
1263  hr = IWICPalette_GetColors(wic_palette, nb_colors, colors, &nb_colors);
1264  if (SUCCEEDED(hr))
1265  {
1266  UINT i;
1267 
1268  /* Convert colors from WICColor (ARGB) to PALETTEENTRY (ABGR) */
1269  for (i = 0; i < nb_colors; i++)
1270  {
1271  palette[i].peRed = (colors[i] >> 16) & 0xff;
1272  palette[i].peGreen = (colors[i] >> 8) & 0xff;
1273  palette[i].peBlue = colors[i] & 0xff;
1274  palette[i].peFlags = (colors[i] >> 24) & 0xff; /* peFlags is the alpha component in DX8 and higher */
1275  }
1276  }
1277  if (wic_palette)
1278  IWICPalette_Release(wic_palette);
1279  }
1280 
1281  if (SUCCEEDED(hr))
1282  {
1283  hr = D3DXLoadSurfaceFromMemory(pDestSurface, pDestPalette, pDestRect,
1284  buffer, imginfo.Format, pitch,
1285  palette, &rect, dwFilter, Colorkey);
1286  }
1287 
1288  HeapFree(GetProcessHeap(), 0, colors);
1289  HeapFree(GetProcessHeap(), 0, palette);
1290  HeapFree(GetProcessHeap(), 0, buffer);
1291  }
1292 
1293  IWICBitmapFrameDecode_Release(bitmapframe);
1294 
1295 cleanup_bmp:
1296  IWICBitmapDecoder_Release(decoder);
1297 
1298 cleanup_err:
1299  if (factory)
1300  IWICImagingFactory_Release(factory);
1301 
1302  if (SUCCEEDED(com_init))
1303  CoUninitialize();
1304 
1305  if (imginfo.ImageFileFormat == D3DXIFF_DIB)
1306  HeapFree(GetProcessHeap(), 0, (void*)pSrcData);
1307 
1308  if (FAILED(hr))
1309  return D3DXERR_INVALIDDATA;
1310 
1311  if (pSrcInfo)
1312  *pSrcInfo = imginfo;
1313 
1314  return D3D_OK;
1315 }
1316 
1317 HRESULT WINAPI D3DXLoadSurfaceFromFileA(IDirect3DSurface9 *dst_surface,
1318  const PALETTEENTRY *dst_palette, const RECT *dst_rect, const char *src_file,
1319  const RECT *src_rect, DWORD filter, D3DCOLOR color_key, D3DXIMAGE_INFO *src_info)
1320 {
1321  WCHAR *src_file_w;
1322  HRESULT hr;
1323  int strlength;
1324 
1325  TRACE("dst_surface %p, dst_palette %p, dst_rect %s, src_file %s, "
1326  "src_rect %s, filter %#x, color_key 0x%08x, src_info %p.\n",
1327  dst_surface, dst_palette, wine_dbgstr_rect(dst_rect), debugstr_a(src_file),
1328  wine_dbgstr_rect(src_rect), filter, color_key, src_info);
1329 
1330  if (!src_file || !dst_surface)
1331  return D3DERR_INVALIDCALL;
1332 
1333  strlength = MultiByteToWideChar(CP_ACP, 0, src_file, -1, NULL, 0);
1334  src_file_w = HeapAlloc(GetProcessHeap(), 0, strlength * sizeof(*src_file_w));
1335  MultiByteToWideChar(CP_ACP, 0, src_file, -1, src_file_w, strlength);
1336 
1337  hr = D3DXLoadSurfaceFromFileW(dst_surface, dst_palette, dst_rect,
1338  src_file_w, src_rect, filter, color_key, src_info);
1339  HeapFree(GetProcessHeap(), 0, src_file_w);
1340 
1341  return hr;
1342 }
1343 
1344 HRESULT WINAPI D3DXLoadSurfaceFromFileW(IDirect3DSurface9 *dst_surface,
1345  const PALETTEENTRY *dst_palette, const RECT *dst_rect, const WCHAR *src_file,
1346  const RECT *src_rect, DWORD filter, D3DCOLOR color_key, D3DXIMAGE_INFO *src_info)
1347 {
1348  UINT data_size;
1349  void *data;
1350  HRESULT hr;
1351 
1352  TRACE("dst_surface %p, dst_palette %p, dst_rect %s, src_file %s, "
1353  "src_rect %s, filter %#x, color_key 0x%08x, src_info %p.\n",
1354  dst_surface, dst_palette, wine_dbgstr_rect(dst_rect), debugstr_w(src_file),
1355  wine_dbgstr_rect(src_rect), filter, color_key, src_info);
1356 
1357  if (!src_file || !dst_surface)
1358  return D3DERR_INVALIDCALL;
1359 
1360  if (FAILED(map_view_of_file(src_file, &data, &data_size)))
1361  return D3DXERR_INVALIDDATA;
1362 
1363  hr = D3DXLoadSurfaceFromFileInMemory(dst_surface, dst_palette, dst_rect,
1364  data, data_size, src_rect, filter, color_key, src_info);
1365  UnmapViewOfFile(data);
1366 
1367  return hr;
1368 }
1369 
1370 HRESULT WINAPI D3DXLoadSurfaceFromResourceA(IDirect3DSurface9 *dst_surface,
1371  const PALETTEENTRY *dst_palette, const RECT *dst_rect, HMODULE src_module, const char *resource,
1372  const RECT *src_rect, DWORD filter, D3DCOLOR color_key, D3DXIMAGE_INFO *src_info)
1373 {
1374  UINT data_size;
1375  HRSRC resinfo;
1376  void *data;
1377 
1378  TRACE("dst_surface %p, dst_palette %p, dst_rect %s, src_module %p, resource %s, "
1379  "src_rect %s, filter %#x, color_key 0x%08x, src_info %p.\n",
1380  dst_surface, dst_palette, wine_dbgstr_rect(dst_rect), src_module, debugstr_a(resource),
1381  wine_dbgstr_rect(src_rect), filter, color_key, src_info);
1382 
1383  if (!dst_surface)
1384  return D3DERR_INVALIDCALL;
1385 
1386  if (!(resinfo = FindResourceA(src_module, resource, (const char *)RT_RCDATA))
1387  /* Try loading the resource as bitmap data (which is in DIB format D3DXIFF_DIB) */
1388  && !(resinfo = FindResourceA(src_module, resource, (const char *)RT_BITMAP)))
1389  return D3DXERR_INVALIDDATA;
1390 
1391  if (FAILED(load_resource_into_memory(src_module, resinfo, &data, &data_size)))
1392  return D3DXERR_INVALIDDATA;
1393 
1394  return D3DXLoadSurfaceFromFileInMemory(dst_surface, dst_palette, dst_rect,
1395  data, data_size, src_rect, filter, color_key, src_info);
1396 }
1397 
1398 HRESULT WINAPI D3DXLoadSurfaceFromResourceW(IDirect3DSurface9 *dst_surface,
1399  const PALETTEENTRY *dst_palette, const RECT *dst_rect, HMODULE src_module, const WCHAR *resource,
1400  const RECT *src_rect, DWORD filter, D3DCOLOR color_key, D3DXIMAGE_INFO *src_info)
1401 {
1402  UINT data_size;
1403  HRSRC resinfo;
1404  void *data;
1405 
1406  TRACE("dst_surface %p, dst_palette %p, dst_rect %s, src_module %p, resource %s, "
1407  "src_rect %s, filter %#x, color_key 0x%08x, src_info %p.\n",
1408  dst_surface, dst_palette, wine_dbgstr_rect(dst_rect), src_module, debugstr_w(resource),
1409  wine_dbgstr_rect(src_rect), filter, color_key, src_info);
1410 
1411  if (!dst_surface)
1412  return D3DERR_INVALIDCALL;
1413 
1414  if (!(resinfo = FindResourceW(src_module, resource, (const WCHAR *)RT_RCDATA))
1415  /* Try loading the resource as bitmap data (which is in DIB format D3DXIFF_DIB) */
1416  && !(resinfo = FindResourceW(src_module, resource, (const WCHAR *)RT_BITMAP)))
1417  return D3DXERR_INVALIDDATA;
1418 
1419  if (FAILED(load_resource_into_memory(src_module, resinfo, &data, &data_size)))
1420  return D3DXERR_INVALIDDATA;
1421 
1422  return D3DXLoadSurfaceFromFileInMemory(dst_surface, dst_palette, dst_rect,
1423  data, data_size, src_rect, filter, color_key, src_info);
1424 }
1425 
1426 
1427 /************************************************************
1428  * helper functions for D3DXLoadSurfaceFromMemory
1429  */
1431 {
1438 };
1439 
1440 static void init_argb_conversion_info(const struct pixel_format_desc *srcformat, const struct pixel_format_desc *destformat, struct argb_conversion_info *info)
1441 {
1442  UINT i;
1443  ZeroMemory(info->process_channel, 4 * sizeof(BOOL));
1444  info->channelmask = 0;
1445 
1446  info->srcformat = srcformat;
1447  info->destformat = destformat;
1448 
1449  for(i = 0;i < 4;i++) {
1450  /* srcshift is used to extract the _relevant_ components */
1451  info->srcshift[i] = srcformat->shift[i] + max( srcformat->bits[i] - destformat->bits[i], 0);
1452 
1453  /* destshift is used to move the components to the correct position */
1454  info->destshift[i] = destformat->shift[i] + max(destformat->bits[i] - srcformat->bits[i], 0);
1455 
1456  info->srcmask[i] = ((1 << srcformat->bits[i]) - 1) << srcformat->shift[i];
1457  info->destmask[i] = ((1 << destformat->bits[i]) - 1) << destformat->shift[i];
1458 
1459  /* channelmask specifies bits which aren't used in the source format but in the destination one */
1460  if(destformat->bits[i]) {
1461  if(srcformat->bits[i]) info->process_channel[i] = TRUE;
1462  else info->channelmask |= info->destmask[i];
1463  }
1464  }
1465 }
1466 
1467 /************************************************************
1468  * get_relevant_argb_components
1469  *
1470  * Extracts the relevant components from the source color and
1471  * drops the less significant bits if they aren't used by the destination format.
1472  */
1473 static void get_relevant_argb_components(const struct argb_conversion_info *info, const BYTE *col, DWORD *out)
1474 {
1475  unsigned int i, j;
1476  unsigned int component, mask;
1477 
1478  for (i = 0; i < 4; ++i)
1479  {
1480  if (!info->process_channel[i])
1481  continue;
1482 
1483  component = 0;
1484  mask = info->srcmask[i];
1485  for (j = 0; j < 4 && mask; ++j)
1486  {
1487  if (info->srcshift[i] < j * 8)
1488  component |= (col[j] & mask) << (j * 8 - info->srcshift[i]);
1489  else
1490  component |= (col[j] & mask) >> (info->srcshift[i] - j * 8);
1491  mask >>= 8;
1492  }
1493  out[i] = component;
1494  }
1495 }
1496 
1497 /************************************************************
1498  * make_argb_color
1499  *
1500  * Recombines the output of get_relevant_argb_components and converts
1501  * it to the destination format.
1502  */
1504 {
1505  UINT i;
1506  DWORD val = 0;
1507 
1508  for(i = 0;i < 4;i++) {
1509  if(info->process_channel[i]) {
1510  /* necessary to make sure that e.g. an X4R4G4B4 white maps to an R8G8B8 white instead of 0xf0f0f0 */
1511  signed int shift;
1512  for(shift = info->destshift[i]; shift > info->destformat->shift[i]; shift -= info->srcformat->bits[i]) val |= in[i] << shift;
1513  val |= (in[i] >> (info->destformat->shift[i] - shift)) << info->destformat->shift[i];
1514  }
1515  }
1516  val |= info->channelmask; /* new channels are set to their maximal value */
1517  return val;
1518 }
1519 
1520 /* It doesn't work for components bigger than 32 bits (or somewhat smaller but unaligned). */
1521 static void format_to_vec4(const struct pixel_format_desc *format, const BYTE *src, struct vec4 *dst)
1522 {
1523  DWORD mask, tmp;
1524  unsigned int c;
1525 
1526  for (c = 0; c < 4; ++c)
1527  {
1528  static const unsigned int component_offsets[4] = {3, 0, 1, 2};
1529  float *dst_component = (float *)dst + component_offsets[c];
1530 
1531  if (format->bits[c])
1532  {
1533  mask = ~0u >> (32 - format->bits[c]);
1534 
1535  memcpy(&tmp, src + format->shift[c] / 8,
1536  min(sizeof(DWORD), (format->shift[c] % 8 + format->bits[c] + 7) / 8));
1537 
1538  if (format->type == FORMAT_ARGBF16)
1539  *dst_component = float_16_to_32(tmp);
1540  else if (format->type == FORMAT_ARGBF)
1541  *dst_component = *(float *)&tmp;
1542  else
1543  *dst_component = (float)((tmp >> format->shift[c] % 8) & mask) / mask;
1544  }
1545  else
1546  *dst_component = 1.0f;
1547  }
1548 }
1549 
1550 /* It doesn't work for components bigger than 32 bits. */
1551 static void format_from_vec4(const struct pixel_format_desc *format, const struct vec4 *src, BYTE *dst)
1552 {
1553  DWORD v, mask32;
1554  unsigned int c, i;
1555 
1556  memset(dst, 0, format->bytes_per_pixel);
1557 
1558  for (c = 0; c < 4; ++c)
1559  {
1560  static const unsigned int component_offsets[4] = {3, 0, 1, 2};
1561  const float src_component = *((const float *)src + component_offsets[c]);
1562 
1563  if (!format->bits[c])
1564  continue;
1565 
1566  mask32 = ~0u >> (32 - format->bits[c]);
1567 
1568  if (format->type == FORMAT_ARGBF16)
1569  v = float_32_to_16(src_component);
1570  else if (format->type == FORMAT_ARGBF)
1571  v = *(DWORD *)&src_component;
1572  else
1573  v = (DWORD)(src_component * ((1 << format->bits[c]) - 1) + 0.5f);
1574 
1575  for (i = format->shift[c] / 8 * 8; i < format->shift[c] + format->bits[c]; i += 8)
1576  {
1577  BYTE mask, byte;
1578 
1579  if (format->shift[c] > i)
1580  {
1581  mask = mask32 << (format->shift[c] - i);
1582  byte = (v << (format->shift[c] - i)) & mask;
1583  }
1584  else
1585  {
1586  mask = mask32 >> (i - format->shift[c]);
1587  byte = (v >> (i - format->shift[c])) & mask;
1588  }
1589  dst[i / 8] |= byte;
1590  }
1591  }
1592 }
1593 
1594 /************************************************************
1595  * copy_pixels
1596  *
1597  * Copies the source buffer to the destination buffer.
1598  * Works for any pixel format.
1599  * The source and the destination must be block-aligned.
1600  */
1601 void copy_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch,
1602  BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch, const struct volume *size,
1603  const struct pixel_format_desc *format)
1604 {
1605  UINT row, slice;
1606  BYTE *dst_addr;
1607  const BYTE *src_addr;
1608  UINT row_block_count = (size->width + format->block_width - 1) / format->block_width;
1609  UINT row_count = (size->height + format->block_height - 1) / format->block_height;
1610 
1611  for (slice = 0; slice < size->depth; slice++)
1612  {
1613  src_addr = src + slice * src_slice_pitch;
1614  dst_addr = dst + slice * dst_slice_pitch;
1615 
1616  for (row = 0; row < row_count; row++)
1617  {
1618  memcpy(dst_addr, src_addr, row_block_count * format->block_byte_count);
1619  src_addr += src_row_pitch;
1620  dst_addr += dst_row_pitch;
1621  }
1622  }
1623 }
1624 
1625 /************************************************************
1626  * convert_argb_pixels
1627  *
1628  * Copies the source buffer to the destination buffer, performing
1629  * any necessary format conversion and color keying.
1630  * Pixels outsize the source rect are blacked out.
1631  */
1632 void convert_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch, const struct volume *src_size,
1633  const struct pixel_format_desc *src_format, BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch,
1634  const struct volume *dst_size, const struct pixel_format_desc *dst_format, D3DCOLOR color_key,
1635  const PALETTEENTRY *palette)
1636 {
1637  struct argb_conversion_info conv_info, ck_conv_info;
1638  const struct pixel_format_desc *ck_format = NULL;
1639  DWORD channels[4];
1640  UINT min_width, min_height, min_depth;
1641  UINT x, y, z;
1642 
1643  ZeroMemory(channels, sizeof(channels));
1644  init_argb_conversion_info(src_format, dst_format, &conv_info);
1645 
1646  min_width = min(src_size->width, dst_size->width);
1647  min_height = min(src_size->height, dst_size->height);
1648  min_depth = min(src_size->depth, dst_size->depth);
1649 
1650  if (color_key)
1651  {
1652  /* Color keys are always represented in D3DFMT_A8R8G8B8 format. */
1653  ck_format = get_format_info(D3DFMT_A8R8G8B8);
1654  init_argb_conversion_info(src_format, ck_format, &ck_conv_info);
1655  }
1656 
1657  for (z = 0; z < min_depth; z++) {
1658  const BYTE *src_slice_ptr = src + z * src_slice_pitch;
1659  BYTE *dst_slice_ptr = dst + z * dst_slice_pitch;
1660 
1661  for (y = 0; y < min_height; y++) {
1662  const BYTE *src_ptr = src_slice_ptr + y * src_row_pitch;
1663  BYTE *dst_ptr = dst_slice_ptr + y * dst_row_pitch;
1664 
1665  for (x = 0; x < min_width; x++) {
1666  if (!src_format->to_rgba && !dst_format->from_rgba
1667  && src_format->type == dst_format->type
1668  && src_format->bytes_per_pixel <= 4 && dst_format->bytes_per_pixel <= 4)
1669  {
1670  DWORD val;
1671 
1672  get_relevant_argb_components(&conv_info, src_ptr, channels);
1673  val = make_argb_color(&conv_info, channels);
1674 
1675  if (color_key)
1676  {
1677  DWORD ck_pixel;
1678 
1679  get_relevant_argb_components(&ck_conv_info, src_ptr, channels);
1680  ck_pixel = make_argb_color(&ck_conv_info, channels);
1681  if (ck_pixel == color_key)
1682  val &= ~conv_info.destmask[0];
1683  }
1684  memcpy(dst_ptr, &val, dst_format->bytes_per_pixel);
1685  }
1686  else
1687  {
1688  struct vec4 color, tmp;
1689 
1690  format_to_vec4(src_format, src_ptr, &color);
1691  if (src_format->to_rgba)
1692  src_format->to_rgba(&color, &tmp, palette);
1693  else
1694  tmp = color;
1695 
1696  if (ck_format)
1697  {
1698  DWORD ck_pixel;
1699 
1700  format_from_vec4(ck_format, &tmp, (BYTE *)&ck_pixel);
1701  if (ck_pixel == color_key)
1702  tmp.w = 0.0f;
1703  }
1704 
1705  if (dst_format->from_rgba)
1706  dst_format->from_rgba(&tmp, &color);
1707  else
1708  color = tmp;
1709 
1710  format_from_vec4(dst_format, &color, dst_ptr);
1711  }
1712 
1713  src_ptr += src_format->bytes_per_pixel;
1714  dst_ptr += dst_format->bytes_per_pixel;
1715  }
1716 
1717  if (src_size->width < dst_size->width) /* black out remaining pixels */
1718  memset(dst_ptr, 0, dst_format->bytes_per_pixel * (dst_size->width - src_size->width));
1719  }
1720 
1721  if (src_size->height < dst_size->height) /* black out remaining pixels */
1722  memset(dst + src_size->height * dst_row_pitch, 0, dst_row_pitch * (dst_size->height - src_size->height));
1723  }
1724  if (src_size->depth < dst_size->depth) /* black out remaining pixels */
1725  memset(dst + src_size->depth * dst_slice_pitch, 0, dst_slice_pitch * (dst_size->depth - src_size->depth));
1726 }
1727 
1728 /************************************************************
1729  * point_filter_argb_pixels
1730  *
1731  * Copies the source buffer to the destination buffer, performing
1732  * any necessary format conversion, color keying and stretching
1733  * using a point filter.
1734  */
1735 void point_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch, const struct volume *src_size,
1736  const struct pixel_format_desc *src_format, BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch,
1737  const struct volume *dst_size, const struct pixel_format_desc *dst_format, D3DCOLOR color_key,
1738  const PALETTEENTRY *palette)
1739 {
1740  struct argb_conversion_info conv_info, ck_conv_info;
1741  const struct pixel_format_desc *ck_format = NULL;
1742  DWORD channels[4];
1743  UINT x, y, z;
1744 
1745  ZeroMemory(channels, sizeof(channels));
1746  init_argb_conversion_info(src_format, dst_format, &conv_info);
1747 
1748  if (color_key)
1749  {
1750  /* Color keys are always represented in D3DFMT_A8R8G8B8 format. */
1751  ck_format = get_format_info(D3DFMT_A8R8G8B8);
1752  init_argb_conversion_info(src_format, ck_format, &ck_conv_info);
1753  }
1754 
1755  for (z = 0; z < dst_size->depth; z++)
1756  {
1757  BYTE *dst_slice_ptr = dst + z * dst_slice_pitch;
1758  const BYTE *src_slice_ptr = src + src_slice_pitch * (z * src_size->depth / dst_size->depth);
1759 
1760  for (y = 0; y < dst_size->height; y++)
1761  {
1762  BYTE *dst_ptr = dst_slice_ptr + y * dst_row_pitch;
1763  const BYTE *src_row_ptr = src_slice_ptr + src_row_pitch * (y * src_size->height / dst_size->height);
1764 
1765  for (x = 0; x < dst_size->width; x++)
1766  {
1767  const BYTE *src_ptr = src_row_ptr + (x * src_size->width / dst_size->width) * src_format->bytes_per_pixel;
1768 
1769  if (!src_format->to_rgba && !dst_format->from_rgba
1770  && src_format->type == dst_format->type
1771  && src_format->bytes_per_pixel <= 4 && dst_format->bytes_per_pixel <= 4)
1772  {
1773  DWORD val;
1774 
1775  get_relevant_argb_components(&conv_info, src_ptr, channels);
1776  val = make_argb_color(&conv_info, channels);
1777 
1778  if (color_key)
1779  {
1780  DWORD ck_pixel;
1781 
1782  get_relevant_argb_components(&ck_conv_info, src_ptr, channels);
1783  ck_pixel = make_argb_color(&ck_conv_info, channels);
1784  if (ck_pixel == color_key)
1785  val &= ~conv_info.destmask[0];
1786  }
1787  memcpy(dst_ptr, &val, dst_format->bytes_per_pixel);
1788  }
1789  else
1790  {
1791  struct vec4 color, tmp;
1792 
1793  format_to_vec4(src_format, src_ptr, &color);
1794  if (src_format->to_rgba)
1795  src_format->to_rgba(&color, &tmp, palette);
1796  else
1797  tmp = color;
1798 
1799  if (ck_format)
1800  {
1801  DWORD ck_pixel;
1802 
1803  format_from_vec4(ck_format, &tmp, (BYTE *)&ck_pixel);
1804  if (ck_pixel == color_key)
1805  tmp.w = 0.0f;
1806  }
1807 
1808  if (dst_format->from_rgba)
1809  dst_format->from_rgba(&tmp, &color);
1810  else
1811  color = tmp;
1812 
1813  format_from_vec4(dst_format, &color, dst_ptr);
1814  }
1815 
1816  dst_ptr += dst_format->bytes_per_pixel;
1817  }
1818  }
1819  }
1820 }
1821 
1822 typedef BOOL (*dxtn_conversion_func)(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out,
1823  enum wined3d_format_id format, unsigned int w, unsigned int h);
1824 
1826 {
1827  switch (format)
1828  {
1829  case D3DFMT_DXT1:
1830  if (!wined3d_dxtn_supported()) return NULL;
1831  return encode ? wined3d_dxt1_encode : wined3d_dxt1_decode;
1832  case D3DFMT_DXT3:
1833  if (!wined3d_dxtn_supported()) return NULL;
1834  return encode ? wined3d_dxt3_encode : wined3d_dxt3_decode;
1835  case D3DFMT_DXT5:
1836  if (!wined3d_dxtn_supported()) return NULL;
1837  return encode ? wined3d_dxt5_encode : wined3d_dxt5_decode;
1838  default:
1839  return NULL;
1840  }
1841 }
1842 
1843 /************************************************************
1844  * D3DXLoadSurfaceFromMemory
1845  *
1846  * Loads data from a given memory chunk into a surface,
1847  * applying any of the specified filters.
1848  *
1849  * PARAMS
1850  * pDestSurface [I] pointer to the surface
1851  * pDestPalette [I] palette to use
1852  * pDestRect [I] to be filled area of the surface
1853  * pSrcMemory [I] pointer to the source data
1854  * SrcFormat [I] format of the source pixel data
1855  * SrcPitch [I] number of bytes in a row
1856  * pSrcPalette [I] palette used in the source image
1857  * pSrcRect [I] area of the source data to load
1858  * dwFilter [I] filter to apply on stretching
1859  * Colorkey [I] colorkey
1860  *
1861  * RETURNS
1862  * Success: D3D_OK, if we successfully load the pixel data into our surface or
1863  * if pSrcMemory is NULL but the other parameters are valid
1864  * Failure: D3DERR_INVALIDCALL, if pDestSurface, SrcPitch or pSrcRect is NULL or
1865  * if SrcFormat is an invalid format (other than D3DFMT_UNKNOWN) or
1866  * if DestRect is invalid
1867  * D3DXERR_INVALIDDATA, if we fail to lock pDestSurface
1868  * E_FAIL, if SrcFormat is D3DFMT_UNKNOWN or the dimensions of pSrcRect are invalid
1869  *
1870  * NOTES
1871  * pSrcRect specifies the dimensions of the source data;
1872  * negative values for pSrcRect are allowed as we're only looking at the width and height anyway.
1873  *
1874  */
1875 HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface,
1876  const PALETTEENTRY *dst_palette, const RECT *dst_rect, const void *src_memory,
1877  D3DFORMAT src_format, UINT src_pitch, const PALETTEENTRY *src_palette, const RECT *src_rect,
1879 {
1880  const struct pixel_format_desc *srcformatdesc, *destformatdesc;
1881  D3DSURFACE_DESC surfdesc;
1882  D3DLOCKED_RECT lockrect;
1883  struct volume src_size, dst_size;
1884  HRESULT ret = D3D_OK;
1885 
1886  TRACE("(%p, %p, %s, %p, %#x, %u, %p, %s, %#x, 0x%08x)\n",
1887  dst_surface, dst_palette, wine_dbgstr_rect(dst_rect), src_memory, src_format,
1888  src_pitch, src_palette, wine_dbgstr_rect(src_rect), filter, color_key);
1889 
1890  if (!dst_surface || !src_memory || !src_rect)
1891  {
1892  WARN("Invalid argument specified.\n");
1893  return D3DERR_INVALIDCALL;
1894  }
1895  if (src_format == D3DFMT_UNKNOWN
1896  || src_rect->left >= src_rect->right
1897  || src_rect->top >= src_rect->bottom)
1898  {
1899  WARN("Invalid src_format or src_rect.\n");
1900  return E_FAIL;
1901  }
1902 
1903  if (filter == D3DX_DEFAULT)
1905 
1906  IDirect3DSurface9_GetDesc(dst_surface, &surfdesc);
1907 
1908  src_size.width = src_rect->right - src_rect->left;
1909  src_size.height = src_rect->bottom - src_rect->top;
1910  src_size.depth = 1;
1911  if (!dst_rect)
1912  {
1913  dst_size.width = surfdesc.Width;
1914  dst_size.height = surfdesc.Height;
1915  }
1916  else
1917  {
1918  if (dst_rect->left > dst_rect->right || dst_rect->right > surfdesc.Width
1919  || dst_rect->top > dst_rect->bottom || dst_rect->bottom > surfdesc.Height
1920  || dst_rect->left < 0 || dst_rect->top < 0)
1921  {
1922  WARN("Invalid dst_rect specified.\n");
1923  return D3DERR_INVALIDCALL;
1924  }
1925  dst_size.width = dst_rect->right - dst_rect->left;
1926  dst_size.height = dst_rect->bottom - dst_rect->top;
1927  if (!dst_size.width || !dst_size.height)
1928  return D3D_OK;
1929  }
1930  dst_size.depth = 1;
1931 
1932  srcformatdesc = get_format_info(src_format);
1933  destformatdesc = get_format_info(surfdesc.Format);
1934  if (srcformatdesc->type == FORMAT_UNKNOWN || destformatdesc->type == FORMAT_UNKNOWN)
1935  {
1936  FIXME("Unsupported pixel format conversion %#x -> %#x\n", src_format, surfdesc.Format);
1937  return E_NOTIMPL;
1938  }
1939 
1940  if (src_format == surfdesc.Format
1941  && dst_size.width == src_size.width
1942  && dst_size.height == src_size.height
1943  && color_key == 0) /* Simple copy. */
1944  {
1945  if (src_rect->left & (srcformatdesc->block_width - 1)
1946  || src_rect->top & (srcformatdesc->block_height - 1)
1947  || (src_rect->right & (srcformatdesc->block_width - 1)
1948  && src_size.width != surfdesc.Width)
1949  || (src_rect->bottom & (srcformatdesc->block_height - 1)
1950  && src_size.height != surfdesc.Height))
1951  {
1952  WARN("Source rect %s is misaligned.\n", wine_dbgstr_rect(src_rect));
1953  return D3DXERR_INVALIDDATA;
1954  }
1955 
1956  if (FAILED(IDirect3DSurface9_LockRect(dst_surface, &lockrect, dst_rect, 0)))
1957  return D3DXERR_INVALIDDATA;
1958 
1959  copy_pixels(src_memory, src_pitch, 0, lockrect.pBits, lockrect.Pitch, 0,
1960  &src_size, srcformatdesc);
1961 
1962  IDirect3DSurface9_UnlockRect(dst_surface);
1963  }
1964  else /* Stretching or format conversion. */
1965  {
1966  dxtn_conversion_func pre_convert, post_convert;
1967  void *tmp_src_memory = NULL, *tmp_dst_memory = NULL;
1968  UINT tmp_src_pitch, tmp_dst_pitch;
1969 
1970  pre_convert = get_dxtn_conversion_func(srcformatdesc->format, FALSE);
1971  post_convert = get_dxtn_conversion_func(destformatdesc->format, TRUE);
1972 
1973  if ((!pre_convert && !is_conversion_from_supported(srcformatdesc)) ||
1974  (!post_convert && !is_conversion_to_supported(destformatdesc)))
1975  {
1976  FIXME("Unsupported format conversion %#x -> %#x.\n", src_format, surfdesc.Format);
1977  return E_NOTIMPL;
1978  }
1979 
1980  if (FAILED(IDirect3DSurface9_LockRect(dst_surface, &lockrect, dst_rect, 0)))
1981  return D3DXERR_INVALIDDATA;
1982 
1983  /* handle pre-conversion */
1984  if (pre_convert)
1985  {
1986  tmp_src_memory = HeapAlloc(GetProcessHeap(), 0, src_size.width * src_size.height * sizeof(DWORD));
1987  if (!tmp_src_memory)
1988  {
1989  ret = E_OUTOFMEMORY;
1990  goto error;
1991  }
1992  tmp_src_pitch = src_size.width * sizeof(DWORD);
1993  if (!pre_convert(src_memory, tmp_src_memory, src_pitch, tmp_src_pitch,
1994  WINED3DFMT_B8G8R8A8_UNORM, src_size.width, src_size.height))
1995  {
1996  ret = E_FAIL;
1997  goto error;
1998  }
1999  srcformatdesc = get_format_info(D3DFMT_A8R8G8B8);
2000  }
2001  else
2002  {
2003  tmp_src_memory = (void *)src_memory;
2004  tmp_src_pitch = src_pitch;
2005  }
2006 
2007  /* handle post-conversion */
2008  if (post_convert)
2009  {
2010  tmp_dst_memory = HeapAlloc(GetProcessHeap(), 0, dst_size.width * dst_size.height * sizeof(DWORD));
2011  if (!tmp_dst_memory)
2012  {
2013  ret = E_OUTOFMEMORY;
2014  goto error;
2015  }
2016  tmp_dst_pitch = dst_size.width * sizeof(DWORD);
2017  destformatdesc = get_format_info(D3DFMT_A8R8G8B8);
2018  }
2019  else
2020  {
2021  tmp_dst_memory = lockrect.pBits;
2022  tmp_dst_pitch = lockrect.Pitch;
2023  }
2024 
2025  if ((filter & 0xf) == D3DX_FILTER_NONE)
2026  {
2027  convert_argb_pixels(tmp_src_memory, tmp_src_pitch, 0, &src_size, srcformatdesc,
2028  tmp_dst_memory, tmp_dst_pitch, 0, &dst_size, destformatdesc, color_key, src_palette);
2029  }
2030  else /* if ((filter & 0xf) == D3DX_FILTER_POINT) */
2031  {
2032  if ((filter & 0xf) != D3DX_FILTER_POINT)
2033  FIXME("Unhandled filter %#x.\n", filter);
2034 
2035  /* Always apply a point filter until D3DX_FILTER_LINEAR,
2036  * D3DX_FILTER_TRIANGLE and D3DX_FILTER_BOX are implemented. */
2037  point_filter_argb_pixels(tmp_src_memory, tmp_src_pitch, 0, &src_size, srcformatdesc,
2038  tmp_dst_memory, tmp_dst_pitch, 0, &dst_size, destformatdesc, color_key, src_palette);
2039  }
2040 
2041  /* handle post-conversion */
2042  if (post_convert)
2043  {
2044  if (!post_convert(tmp_dst_memory, lockrect.pBits, tmp_dst_pitch, lockrect.Pitch,
2045  WINED3DFMT_B8G8R8A8_UNORM, dst_size.width, dst_size.height))
2046  {
2047  ret = E_FAIL;
2048  goto error;
2049  }
2050  }
2051 
2052 error:
2053  if (pre_convert)
2054  HeapFree(GetProcessHeap(), 0, tmp_src_memory);
2055  if (post_convert)
2056  HeapFree(GetProcessHeap(), 0, tmp_dst_memory);
2057  IDirect3DSurface9_UnlockRect(dst_surface);
2058  }
2059 
2060  return ret;
2061 }
2062 
2063 /************************************************************
2064  * D3DXLoadSurfaceFromSurface
2065  *
2066  * Copies the contents from one surface to another, performing any required
2067  * format conversion, resizing or filtering.
2068  *
2069  * PARAMS
2070  * pDestSurface [I] pointer to the destination surface
2071  * pDestPalette [I] palette to use
2072  * pDestRect [I] to be filled area of the surface
2073  * pSrcSurface [I] pointer to the source surface
2074  * pSrcPalette [I] palette used for the source surface
2075  * pSrcRect [I] area of the source data to load
2076  * dwFilter [I] filter to apply on resizing
2077  * Colorkey [I] any ARGB value or 0 to disable color-keying
2078  *
2079  * RETURNS
2080  * Success: D3D_OK
2081  * Failure: D3DERR_INVALIDCALL, if pDestSurface or pSrcSurface is NULL
2082  * D3DXERR_INVALIDDATA, if one of the surfaces is not lockable
2083  *
2084  */
2085 HRESULT WINAPI D3DXLoadSurfaceFromSurface(IDirect3DSurface9 *dst_surface,
2086  const PALETTEENTRY *dst_palette, const RECT *dst_rect, IDirect3DSurface9 *src_surface,
2087  const PALETTEENTRY *src_palette, const RECT *src_rect, DWORD filter, D3DCOLOR color_key)
2088 {
2089  RECT rect;
2091  D3DSURFACE_DESC SrcDesc;
2092  HRESULT hr;
2093 
2094  TRACE("dst_surface %p, dst_palette %p, dst_rect %s, src_surface %p, "
2095  "src_palette %p, src_rect %s, filter %#x, color_key 0x%08x.\n",
2096  dst_surface, dst_palette, wine_dbgstr_rect(dst_rect), src_surface,
2097  src_palette, wine_dbgstr_rect(src_rect), filter, color_key);
2098 
2099  if (!dst_surface || !src_surface)
2100  return D3DERR_INVALIDCALL;
2101 
2102  IDirect3DSurface9_GetDesc(src_surface, &SrcDesc);
2103 
2104  if (!src_rect)
2105  SetRect(&rect, 0, 0, SrcDesc.Width, SrcDesc.Height);
2106  else
2107  rect = *src_rect;
2108 
2109  if (FAILED(IDirect3DSurface9_LockRect(src_surface, &lock, NULL, D3DLOCK_READONLY)))
2110  return D3DXERR_INVALIDDATA;
2111 
2112  hr = D3DXLoadSurfaceFromMemory(dst_surface, dst_palette, dst_rect,
2113  lock.pBits, SrcDesc.Format, lock.Pitch, src_palette, &rect, filter, color_key);
2114 
2115  IDirect3DSurface9_UnlockRect(src_surface);
2116 
2117  return hr;
2118 }
2119 
2120 
2121 HRESULT WINAPI D3DXSaveSurfaceToFileA(const char *dst_filename, D3DXIMAGE_FILEFORMAT file_format,
2122  IDirect3DSurface9 *src_surface, const PALETTEENTRY *src_palette, const RECT *src_rect)
2123 {
2124  int len;
2125  WCHAR *filename;
2126  HRESULT hr;
2128 
2129  TRACE("(%s, %#x, %p, %p, %s): relay\n",
2130  wine_dbgstr_a(dst_filename), file_format, src_surface, src_palette, wine_dbgstr_rect(src_rect));
2131 
2132  if (!dst_filename) return D3DERR_INVALIDCALL;
2133 
2134  len = MultiByteToWideChar(CP_ACP, 0, dst_filename, -1, NULL, 0);
2135  filename = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2136  if (!filename) return E_OUTOFMEMORY;
2137  MultiByteToWideChar(CP_ACP, 0, dst_filename, -1, filename, len);
2138 
2139  hr = D3DXSaveSurfaceToFileInMemory(&buffer, file_format, src_surface, src_palette, src_rect);
2140  if (SUCCEEDED(hr))
2141  {
2142  hr = write_buffer_to_file(filename, buffer);
2143  ID3DXBuffer_Release(buffer);
2144  }
2145 
2146  HeapFree(GetProcessHeap(), 0, filename);
2147  return hr;
2148 }
2149 
2151  IDirect3DSurface9 *src_surface, const PALETTEENTRY *src_palette, const RECT *src_rect)
2152 {
2153  HRESULT hr;
2155 
2156  TRACE("(%s, %#x, %p, %p, %s): relay\n",
2157  wine_dbgstr_w(dst_filename), file_format, src_surface, src_palette, wine_dbgstr_rect(src_rect));
2158 
2159  if (!dst_filename) return D3DERR_INVALIDCALL;
2160 
2161  hr = D3DXSaveSurfaceToFileInMemory(&buffer, file_format, src_surface, src_palette, src_rect);
2162  if (SUCCEEDED(hr))
2163  {
2164  hr = write_buffer_to_file(dst_filename, buffer);
2165  ID3DXBuffer_Release(buffer);
2166  }
2167 
2168  return hr;
2169 }
2170 
2172  IDirect3DSurface9 *src_surface, const PALETTEENTRY *src_palette, const RECT *src_rect)
2173 {
2174  IWICBitmapEncoder *encoder = NULL;
2175  IWICBitmapFrameEncode *frame = NULL;
2176  IPropertyBag2 *encoder_options = NULL;
2177  IStream *stream = NULL;
2178  HRESULT hr;
2179  HRESULT initresult;
2180  const CLSID *encoder_clsid;
2181  const GUID *pixel_format_guid;
2182  WICPixelFormatGUID wic_pixel_format;
2183  D3DFORMAT d3d_pixel_format;
2184  D3DSURFACE_DESC src_surface_desc;
2185  D3DLOCKED_RECT locked_rect;
2186  int width, height;
2187  STATSTG stream_stats;
2188  HGLOBAL stream_hglobal;
2190  DWORD size;
2191 
2192  TRACE("(%p, %#x, %p, %p, %s)\n",
2193  dst_buffer, file_format, src_surface, src_palette, wine_dbgstr_rect(src_rect));
2194 
2195  if (!dst_buffer || !src_surface) return D3DERR_INVALIDCALL;
2196 
2197  if (src_palette)
2198  {
2199  FIXME("Saving surfaces with palettized pixel formats is not implemented yet\n");
2200  return D3DERR_INVALIDCALL;
2201  }
2202 
2203  switch (file_format)
2204  {
2205  case D3DXIFF_BMP:
2206  case D3DXIFF_DIB:
2207  encoder_clsid = &CLSID_WICBmpEncoder;
2208  break;
2209  case D3DXIFF_PNG:
2210  encoder_clsid = &CLSID_WICPngEncoder;
2211  break;
2212  case D3DXIFF_JPG:
2213  encoder_clsid = &CLSID_WICJpegEncoder;
2214  break;
2215  case D3DXIFF_DDS:
2216  return save_dds_surface_to_memory(dst_buffer, src_surface, src_rect);
2217  case D3DXIFF_HDR:
2218  case D3DXIFF_PFM:
2219  case D3DXIFF_TGA:
2220  case D3DXIFF_PPM:
2221  FIXME("File format %#x is not supported yet\n", file_format);
2222  return E_NOTIMPL;
2223  default:
2224  return D3DERR_INVALIDCALL;
2225  }
2226 
2227  IDirect3DSurface9_GetDesc(src_surface, &src_surface_desc);
2228  if (src_rect)
2229  {
2230  if (src_rect->left == src_rect->right || src_rect->top == src_rect->bottom)
2231  {
2232  WARN("Invalid rectangle with 0 area\n");
2233  return D3DXCreateBuffer(64, dst_buffer);
2234  }
2235  if (src_rect->left < 0 || src_rect->top < 0)
2236  return D3DERR_INVALIDCALL;
2237  if (src_rect->left > src_rect->right || src_rect->top > src_rect->bottom)
2238  return D3DERR_INVALIDCALL;
2239  if (src_rect->right > src_surface_desc.Width || src_rect->bottom > src_surface_desc.Height)
2240  return D3DERR_INVALIDCALL;
2241 
2242  width = src_rect->right - src_rect->left;
2243  height = src_rect->bottom - src_rect->top;
2244  }
2245  else
2246  {
2247  width = src_surface_desc.Width;
2248  height = src_surface_desc.Height;
2249  }
2250 
2252 
2253  hr = CoCreateInstance(encoder_clsid, NULL, CLSCTX_INPROC_SERVER,
2254  &IID_IWICBitmapEncoder, (void **)&encoder);
2255  if (FAILED(hr)) goto cleanup_err;
2256 
2257  hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
2258  if (FAILED(hr)) goto cleanup_err;
2259 
2260  hr = IWICBitmapEncoder_Initialize(encoder, stream, WICBitmapEncoderNoCache);
2261  if (FAILED(hr)) goto cleanup_err;
2262 
2263  hr = IWICBitmapEncoder_CreateNewFrame(encoder, &frame, &encoder_options);
2264  if (FAILED(hr)) goto cleanup_err;
2265 
2266  hr = IWICBitmapFrameEncode_Initialize(frame, encoder_options);
2267  if (FAILED(hr)) goto cleanup_err;
2268 
2269  hr = IWICBitmapFrameEncode_SetSize(frame, width, height);
2270  if (FAILED(hr)) goto cleanup_err;
2271 
2272  pixel_format_guid = d3dformat_to_wic_guid(src_surface_desc.Format);
2273  if (!pixel_format_guid)
2274  {
2275  FIXME("Pixel format %#x is not supported yet\n", src_surface_desc.Format);
2276  hr = E_NOTIMPL;
2277  goto cleanup;
2278  }
2279 
2280  memcpy(&wic_pixel_format, pixel_format_guid, sizeof(GUID));
2281  hr = IWICBitmapFrameEncode_SetPixelFormat(frame, &wic_pixel_format);
2282  d3d_pixel_format = wic_guid_to_d3dformat(&wic_pixel_format);
2283  if (SUCCEEDED(hr) && d3d_pixel_format != D3DFMT_UNKNOWN)
2284  {
2285  TRACE("Using pixel format %s %#x\n", debugstr_guid(&wic_pixel_format), d3d_pixel_format);
2286 
2287  if (src_surface_desc.Format == d3d_pixel_format) /* Simple copy */
2288  {
2289  hr = IDirect3DSurface9_LockRect(src_surface, &locked_rect, src_rect, D3DLOCK_READONLY);
2290  if (SUCCEEDED(hr))
2291  {
2292  IWICBitmapFrameEncode_WritePixels(frame, height,
2293  locked_rect.Pitch, height * locked_rect.Pitch, locked_rect.pBits);
2294  IDirect3DSurface9_UnlockRect(src_surface);
2295  }
2296  }
2297  else /* Pixel format conversion */
2298  {
2299  const struct pixel_format_desc *src_format_desc, *dst_format_desc;
2300  struct volume size;
2301  DWORD dst_pitch;
2302  void *dst_data;
2303 
2304  src_format_desc = get_format_info(src_surface_desc.Format);
2305  dst_format_desc = get_format_info(d3d_pixel_format);
2306  if (!is_conversion_from_supported(src_format_desc)
2307  || !is_conversion_to_supported(dst_format_desc))
2308  {
2309  FIXME("Unsupported format conversion %#x -> %#x.\n",
2310  src_surface_desc.Format, d3d_pixel_format);
2311  hr = E_NOTIMPL;
2312  goto cleanup;
2313  }
2314 
2315  size.width = width;
2316  size.height = height;
2317  size.depth = 1;
2318  dst_pitch = width * dst_format_desc->bytes_per_pixel;
2319  dst_data = HeapAlloc(GetProcessHeap(), 0, dst_pitch * height);
2320  if (!dst_data)
2321  {
2322  hr = E_OUTOFMEMORY;
2323  goto cleanup;
2324  }
2325 
2326  hr = IDirect3DSurface9_LockRect(src_surface, &locked_rect, src_rect, D3DLOCK_READONLY);
2327  if (SUCCEEDED(hr))
2328  {
2329  convert_argb_pixels(locked_rect.pBits, locked_rect.Pitch, 0, &size, src_format_desc,
2330  dst_data, dst_pitch, 0, &size, dst_format_desc, 0, NULL);
2331  IDirect3DSurface9_UnlockRect(src_surface);
2332  }
2333 
2334  IWICBitmapFrameEncode_WritePixels(frame, height, dst_pitch, dst_pitch * height, dst_data);
2335  HeapFree(GetProcessHeap(), 0, dst_data);
2336  }
2337 
2338  hr = IWICBitmapFrameEncode_Commit(frame);
2339  if (SUCCEEDED(hr)) hr = IWICBitmapEncoder_Commit(encoder);
2340  }
2341  else WARN("Unsupported pixel format %#x\n", src_surface_desc.Format);
2342 
2343  /* copy data from stream to ID3DXBuffer */
2344  hr = IStream_Stat(stream, &stream_stats, STATFLAG_NONAME);
2345  if (FAILED(hr)) goto cleanup_err;
2346 
2347  if (stream_stats.cbSize.u.HighPart != 0)
2348  {
2349  hr = D3DXERR_INVALIDDATA;
2350  goto cleanup;
2351  }
2352  size = stream_stats.cbSize.u.LowPart;
2353 
2354  /* Remove BMP header for DIB */
2355  if (file_format == D3DXIFF_DIB)
2356  size -= sizeof(BITMAPFILEHEADER);
2357 
2358  hr = D3DXCreateBuffer(size, &buffer);
2359  if (FAILED(hr)) goto cleanup;
2360 
2361  hr = GetHGlobalFromStream(stream, &stream_hglobal);
2362  if (SUCCEEDED(hr))
2363  {
2364  void *buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer);
2365  void *stream_data = GlobalLock(stream_hglobal);
2366  /* Remove BMP header for DIB */
2367  if (file_format == D3DXIFF_DIB)
2368  stream_data = (void*)((BYTE*)stream_data + sizeof(BITMAPFILEHEADER));
2369  memcpy(buffer_pointer, stream_data, size);
2370  GlobalUnlock(stream_hglobal);
2371  *dst_buffer = buffer;
2372  }
2373  else ID3DXBuffer_Release(buffer);
2374 
2375 cleanup_err:
2376  if (FAILED(hr) && hr != E_OUTOFMEMORY)
2377  hr = D3DERR_INVALIDCALL;
2378 
2379 cleanup:
2380  if (stream) IStream_Release(stream);
2381 
2382  if (frame) IWICBitmapFrameEncode_Release(frame);
2383  if (encoder_options) IPropertyBag2_Release(encoder_options);
2384 
2385  if (encoder) IWICBitmapEncoder_Release(encoder);
2386 
2387  if (SUCCEEDED(initresult)) CoUninitialize();
2388 
2389  return hr;
2390 }
DWORD amask
Definition: surface.c:185
#define IDirect3DSurface9_Release(p)
Definition: d3d9.h:622
HANDLE HGLOBAL
Definition: windef.h:243
HRESULT save_dds_texture_to_memory(ID3DXBuffer **dst_buffer, IDirect3DBaseTexture9 *src_texture, const PALETTEENTRY *src_palette)
Definition: surface.c:562
UINT width
Definition: d3dx9_private.h:44
GLint level
Definition: gl.h:1546
#define max(a, b)
Definition: svc.c:63
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble const GLfloat const GLdouble const GLfloat GLenum GLint GLint GLint GLint GLint GLint j
Definition: glfuncs.h:98
#define TRUE
Definition: types.h:120
#define shift
Definition: input.c:1668
HRESULT WINAPI GetHGlobalFromStream(IStream *pstm, HGLOBAL *phglobal)
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
static const GUID * d3dformat_to_wic_guid(D3DFORMAT format)
Definition: surface.c:67
#define DDS_CAPS
Definition: surface.c:81
HRESULT WINAPI D3DXLoadSurfaceFromResourceW(IDirect3DSurface9 *dst_surface, const PALETTEENTRY *dst_palette, const RECT *dst_rect, HMODULE src_module, const WCHAR *resource, const RECT *src_rect, DWORD filter, D3DCOLOR color_key, D3DXIMAGE_INFO *src_info)
Definition: surface.c:1398
rwlock_t lock
Definition: tcpcore.h:1163
DWORD miplevels
Definition: surface.c:139
static D3DFORMAT dds_bump_luminance_to_d3dformat(const struct dds_pixel_format *pixel_format)
Definition: surface.c:271
const char int int int static __inline const char * wine_dbgstr_a(const char *s)
Definition: debug.h:184
#define error(str)
Definition: mkdosfs.c:1605
HRESULT WINAPI D3DXLoadSurfaceFromSurface(IDirect3DSurface9 *dst_surface, const PALETTEENTRY *dst_palette, const RECT *dst_rect, IDirect3DSurface9 *src_surface, const PALETTEENTRY *src_palette, const RECT *src_rect, DWORD filter, D3DCOLOR color_key)
Definition: surface.c:2085
static const char * dst_format
Definition: dib.c:1133
D3DFORMAT Format
Definition: d3d8types.h:1170
BOOL wined3d_dxtn_supported(void)
Definition: dxtn.c:510
#define IDirect3DCubeTexture9_GetLevelCount(p)
Definition: d3d9.h:932
DWORD caps2
Definition: surface.c:143
#define IDirect3DTexture9_GetSurfaceLevel(p, a, b)
Definition: d3d9.h:1033
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define DDS_PF_FOURCC
Definition: surface.c:111
BOOL wined3d_dxt3_encode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out, enum wined3d_format_id format, unsigned int w, unsigned int h)
Definition: dxtn.c:417
#define CP_ACP
Definition: compat.h:99
BOOL wined3d_dxt5_encode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out, enum wined3d_format_id format, unsigned int w, unsigned int h)
Definition: dxtn.c:439
#define WARN(fmt,...)
Definition: debug.h:111
#define IDirect3DVolumeTexture9_GetLevelCount(p)
Definition: d3d9.h:1122
HRSRC WINAPI FindResourceA(HMODULE hModule, LPCSTR name, LPCSTR type)
Definition: res.c:155
GLintptr offset
Definition: glext.h:5920
#define D3DX_FILTER_NONE
Definition: d3dx9tex.h:27
DWORD caps4
Definition: surface.c:145
#define DDS_CAPS_TEXTURE
Definition: surface.c:92
#define DDS_CAPS2_VOLUME
Definition: surface.c:106
LONG top
Definition: windef.h:297
#define D3DERR_INVALIDCALL
HRESULT WINAPI D3DXLoadSurfaceFromFileW(IDirect3DSurface9 *dst_surface, const PALETTEENTRY *dst_palette, const RECT *dst_rect, const WCHAR *src_file, const RECT *src_rect, DWORD filter, D3DCOLOR color_key, D3DXIMAGE_INFO *src_info)
Definition: surface.c:1344
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define ZeroMemory
Definition: winbase.h:1635
GLuint buffer
Definition: glext.h:5915
BOOL wined3d_dxt1_decode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out, enum wined3d_format_id format, unsigned int w, unsigned int h)
Definition: dxtn.c:317
int This channels
Definition: rdpsnd_libao.c:37
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm)
static D3DFORMAT dds_alpha_to_d3dformat(const struct dds_pixel_format *pixel_format)
Definition: surface.c:250
DWORD flags
Definition: surface.c:134
const struct pixel_format_desc * srcformat
Definition: surface.c:1432
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble * u
Definition: glfuncs.h:88
HRESULT WINAPI D3DXLoadSurfaceFromFileA(IDirect3DSurface9 *dst_surface, const PALETTEENTRY *dst_palette, const RECT *dst_rect, const char *src_file, const RECT *src_rect, DWORD filter, D3DCOLOR color_key, D3DXIMAGE_INFO *src_info)
Definition: surface.c:1317
#define IDirect3DTexture9_GetLevelCount(p)
Definition: d3d9.h:1027
DWORD reserved[11]
Definition: surface.c:140
LONG left
Definition: windef.h:296
D3DFORMAT format
Definition: surface.c:186
enum _D3DXIMAGE_FILEFORMAT D3DXIMAGE_FILEFORMAT
WORD face[3]
Definition: mesh.c:4747
const char * filename
Definition: ioapi.h:135
LONG right
Definition: windef.h:298
#define E_FAIL
Definition: ddrawi.h:102
DWORD width
Definition: surface.c:136
#define DWORD
Definition: msvc.h:34
D3DRESOURCETYPE ResourceType
Definition: d3dx9tex.h:83
GLuint const GLubyte mask[]
Definition: s_context.h:57
#define DDS_PF_BUMPDUDV
Definition: surface.c:116
#define BI_BITFIELDS
Definition: mmreg.h:507
DWORD caps3
Definition: surface.c:144
& rect
Definition: startmenu.cpp:1413
DWORD DWORD
Definition: winlogon.h:75
HRSRC WINAPI FindResourceW(HINSTANCE hModule, LPCWSTR name, LPCWSTR type)
Definition: res.c:176
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
static HRESULT get_surface(D3DRESOURCETYPE type, struct IDirect3DBaseTexture9 *tex, int face, UINT level, struct IDirect3DSurface9 **surf)
Definition: surface.c:547
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
void convert_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch, const struct volume *src_size, const struct pixel_format_desc *src_format, BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch, const struct volume *dst_size, const struct pixel_format_desc *dst_format, D3DCOLOR color_key, const PALETTEENTRY *palette)
Definition: surface.c:1632
GLuint const GLubyte GLvoid * src
Definition: s_context.h:57
UINT MipLevels
Definition: d3dx9tex.h:81
GLenum GLclampf GLint i
Definition: glfuncs.h:14
const GUID * guid
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define FALSE
Definition: types.h:117
UINT Back
Definition: d3d8types.h:1016
const GUID * wic_guid
Definition: surface.c:40
Definition: main.c:440
GLuint color
Definition: glext.h:6243
DWORD height
Definition: surface.c:135
static const struct @243 rgb_pixel_formats[]
DWORD destshift[4]
Definition: surface.c:1434
#define debugstr_w
Definition: kernel32.h:32
static D3DFORMAT dds_rgb_to_d3dformat(const struct dds_pixel_format *pixel_format)
Definition: surface.c:205
HRESULT load_resource_into_memory(HMODULE module, HRSRC resinfo, void **buffer, DWORD *length) DECLSPEC_HIDDEN
Definition: util.c:166
#define FIXME(fmt,...)
Definition: debug.h:110
#define D3DX_DEFAULT
Definition: d3dx9.h:24
#define DDS_PIXELFORMAT
Definition: surface.c:85
DWORD biCompression
Definition: amvideo.idl:35
char * wine_dbgstr_w(const wchar_t *wstr)
Definition: CString.cpp:62
HRESULT WINAPI D3DXLoadSurfaceFromResourceA(IDirect3DSurface9 *dst_surface, const PALETTEENTRY *dst_palette, const RECT *dst_rect, HMODULE src_module, const char *resource, const RECT *src_rect, DWORD filter, D3DCOLOR color_key, D3DXIMAGE_INFO *src_info)
Definition: surface.c:1370
#define D3DX_FILTER_TRIANGLE
Definition: d3dx9tex.h:30
static BOOL is_conversion_from_supported(const struct pixel_format_desc *format)
Definition: d3dx9_private.h:80
BOOL wined3d_dxt1_encode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out, enum wined3d_format_id format, unsigned int w, unsigned int h)
Definition: dxtn.c:389
GLdouble GLdouble z
Definition: glext.h:5874
DWORD size
Definition: surface.c:133
UINT height
Definition: d3dx9_private.h:45
smooth NULL
Definition: ftsmooth.c:416
HRESULT write_buffer_to_file(const WCHAR *filename, ID3DXBuffer *buffer) DECLSPEC_HIDDEN
Definition: util.c:182
DWORD signature
Definition: surface.c:132
struct ID3DXBuffer ID3DXBuffer
Definition: d3dx8core.h:51
enum _D3DFORMAT D3DFORMAT
INT Height
Definition: wincodec.idl:239
#define debugstr_guid
Definition: kernel32.h:35
#define ARRAY_SIZE(A)
Definition: reg.h:24
UINT Bottom
Definition: d3d8types.h:1014
BOOL process_channel[4]
Definition: surface.c:1436
static D3DFORMAT wic_guid_to_d3dformat(const GUID *guid)
Definition: surface.c:54
#define IDirect3DBaseTexture9_GetType(p)
Definition: d3d9.h:844
GLuint GLfloat * val
Definition: glext.h:7180
DEFINE_GUID(GUID_WineContainerFormatTga, 0x0c44fda1, 0xa5c5, 0x4298, 0x96, 0x85, 0x47, 0x3f, 0xc1, 0x7c, 0xd3, 0x22)
GLfloat f
Definition: glext.h:7540
float float_16_to_32(const unsigned short in) DECLSPEC_HIDDEN
Definition: math.c:2237
D3DFORMAT d3dformat
Definition: surface.c:41
D3DXIMAGE_FILEFORMAT ImageFileFormat
Definition: d3dx9tex.h:84
#define TRACE(s)
Definition: solgame.cpp:4
UINT depth
Definition: d3dx9_private.h:46
unsigned int BOOL
Definition: ntddk_ex.h:94
GLsizeiptr size
Definition: glext.h:5919
static D3DFORMAT dds_fourcc_to_d3dformat(DWORD fourcc)
Definition: surface.c:149
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
DWORD reserved2
Definition: surface.c:146
GLint GLint GLsizei width
Definition: gl.h:1546
if(!(yy_init))
Definition: macro.lex.yy.c:717
D3DFORMAT Format
Definition: d3dx9tex.h:82
UINT Top
Definition: d3d8types.h:1012
#define DDS_CAPS2_CUBEMAP_ALL_FACES
Definition: surface.c:103
#define debugstr_a
Definition: kernel32.h:31
GLenum GLuint texture
Definition: glext.h:6295
LONG HRESULT
Definition: typedefs.h:77
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define DDS_PF_BUMPLUMINANCE
Definition: surface.c:115
UINT Left
Definition: d3d8types.h:1011
HRESULT load_texture_from_dds(IDirect3DTexture9 *texture, const void *src_data, const PALETTEENTRY *palette, DWORD filter, D3DCOLOR color_key, const D3DXIMAGE_INFO *src_info, unsigned int skip_levels, unsigned int *loaded_miplevels)
Definition: surface.c:627
static HRESULT calculate_dds_surface_size(D3DFORMAT format, UINT width, UINT height, UINT *pitch, UINT *size)
Definition: surface.c:343
const char * wine_dbgstr_rect(const RECT *rect)
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
#define CopyMemory
Definition: winbase.h:1633
enum format_type type
Definition: d3dx9_private.h:67
static FILE * out
Definition: regtests2xml.c:44
HRESULT WINAPI D3DXGetImageInfoFromFileA(const char *file, D3DXIMAGE_INFO *info)
Definition: surface.c:1031
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define RT_RCDATA
Definition: pedump.c:372
float w
Definition: d3dx9_private.h:39
HRESULT map_view_of_file(const WCHAR *filename, void **buffer, DWORD *length) DECLSPEC_HIDDEN
Definition: util.c:118
HRESULT WINAPI D3DXGetImageInfoFromFileW(const WCHAR *file, D3DXIMAGE_INFO *info)
Definition: surface.c:1051
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
int ret
HRESULT WINAPI D3DXSaveSurfaceToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE_FILEFORMAT file_format, IDirect3DSurface9 *src_surface, const PALETTEENTRY *src_palette, const RECT *src_rect)
Definition: surface.c:2171
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
Definition: parse.h:22
GLuint GLuint stream
Definition: glext.h:7522
#define IDirect3DCubeTexture9_GetCubeMapSurface(p, a, b, c)
Definition: d3d9.h:938
#define IDirect3DVolume9_Release(p)
Definition: d3d9.h:383
HRESULT load_volume_texture_from_dds(IDirect3DVolumeTexture9 *volume_texture, const void *src_data, const PALETTEENTRY *palette, DWORD filter, DWORD color_key, const D3DXIMAGE_INFO *src_info)
Definition: surface.c:737
BOOL(* dxtn_conversion_func)(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out, enum wined3d_format_id format, unsigned int w, unsigned int h)
Definition: surface.c:1822
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
DWORD pitch_or_linear_size
Definition: surface.c:137
GLenum GLsizei len
Definition: glext.h:6722
static UINT calculate_dds_file_size(D3DFORMAT format, UINT width, UINT height, UINT depth, UINT miplevels, UINT faces)
Definition: surface.c:366
#define WINAPI
Definition: msvc.h:20
#define IDirect3DSurface9_GetDesc(p, a)
Definition: d3d9.h:634
static HPALETTE palette
Definition: clipboard.c:1345
static const struct @242 wic_pixel_formats[]
static dxtn_conversion_func get_dxtn_conversion_func(D3DFORMAT format, BOOL encode)
Definition: surface.c:1825
unsigned char BYTE
Definition: ntddk_ex.h:96
GLfloat CONST GLvector4f * in
Definition: m_xform.h:122
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3237
wined3d_format_id
Definition: wined3d.h:105
#define DDS_PF_LUMINANCE
Definition: surface.c:114
#define ERR(fmt,...)
Definition: debug.h:109
static D3DFORMAT dds_luminance_to_d3dformat(const struct dds_pixel_format *pixel_format)
Definition: surface.c:228
BOOL wined3d_dxt3_decode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out, enum wined3d_format_id format, unsigned int w, unsigned int h)
Definition: dxtn.c:345
static void format_from_vec4(const struct pixel_format_desc *format, const struct vec4 *src, BYTE *dst)
Definition: surface.c:1551
WINE_DEFAULT_DEBUG_CHANNEL(d3d8)
static void init_argb_conversion_info(const struct pixel_format_desc *srcformat, const struct pixel_format_desc *destformat, struct argb_conversion_info *info)
Definition: surface.c:1440
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)
#define D3D_OK
Definition: d3d.h:106
HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface, const PALETTEENTRY *dst_palette, const RECT *dst_rect, const void *src_memory, D3DFORMAT src_format, UINT src_pitch, const PALETTEENTRY *src_palette, const RECT *src_rect, DWORD filter, D3DCOLOR color_key)
Definition: surface.c:1875
HRESULT WINAPI D3DXSaveSurfaceToFileA(const char *dst_filename, D3DXIMAGE_FILEFORMAT file_format, IDirect3DSurface9 *src_surface, const PALETTEENTRY *src_palette, const RECT *src_rect)
Definition: surface.c:2121
#define D3DX_FILTER_DITHER
Definition: d3dx9tex.h:36
const GLdouble * v
Definition: gl.h:2040
#define DDS_PF_RGB
Definition: surface.c:112
#define byte(x, n)
Definition: tomcrypt.h:118
HRESULT WINAPI D3DXLoadVolumeFromMemory(IDirect3DVolume9 *dst_volume, const PALETTEENTRY *dst_palette, const D3DBOX *dst_box, const void *src_memory, D3DFORMAT src_format, UINT src_row_pitch, UINT src_slice_pitch, const PALETTEENTRY *src_palette, const D3DBOX *src_box, DWORD filter, D3DCOLOR color_key)
Definition: volume.c:85
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:1994
#define ID3DXBuffer_Release(p)
Definition: d3dx9core.h:83
UINT Front
Definition: d3d8types.h:1015
struct tagBITMAPFILEHEADER BITMAPFILEHEADER
#define DDS_WIDTH
Definition: surface.c:83
#define E_NOTIMPL
Definition: ddrawi.h:99
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: gl.h:1546
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
Definition: compobj.c:1938
#define DDS_PF_ALPHA
Definition: surface.c:109
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4024
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
GLuint const GLubyte GLvoid const GLvoid * dst
Definition: s_context.h:57
struct dds_pixel_format pixel_format
Definition: surface.c:141
static const BYTE dib[]
Definition: ole2.c:207
static HRESULT load_surface_from_dds(IDirect3DSurface9 *dst_surface, const PALETTEENTRY *dst_palette, const RECT *dst_rect, const void *src_data, const RECT *src_rect, DWORD filter, D3DCOLOR color_key, const D3DXIMAGE_INFO *src_info)
Definition: surface.c:459
static BOOL is_conversion_to_supported(const struct pixel_format_desc *format)
Definition: d3dx9_private.h:88
#define MultiByteToWideChar
Definition: compat.h:100
HRESULT WINAPI D3DXGetImageInfoFromResourceA(HMODULE module, const char *resource, D3DXIMAGE_INFO *info)
Definition: surface.c:1080
static D3DFORMAT dds_pixel_format_to_d3dformat(const struct dds_pixel_format *pixel_format)
Definition: surface.c:282
static HRESULT get_image_info_from_dds(const void *buffer, UINT length, D3DXIMAGE_INFO *info)
Definition: surface.c:403
HANDLE HMODULE
Definition: typedefs.h:75
#define IDirect3DSurface9_UnlockRect(p)
Definition: d3d9.h:636
static unsigned short float_32_to_16(const float *in)
Definition: surface.c:572
#define DDS_CAPS2_CUBEMAP_NEGATIVEZ
Definition: surface.c:102
INT Width
Definition: wincodec.idl:238
#define IDirect3DVolumeTexture9_GetVolumeLevel(p, a, b)
Definition: d3d9.h:1128
static D3DFORMAT dds_bump_to_d3dformat(const struct dds_pixel_format *pixel_format)
Definition: surface.c:259
UINT Right
Definition: d3d8types.h:1013
#define c
Definition: ke_i.h:80
#define DDS_HEIGHT
Definition: surface.c:82
unsigned int ULONG
Definition: retypes.h:1
#define D3DX_FILTER_POINT
Definition: d3dx9tex.h:28
static ClassFactoryImpl factory
Definition: ole_server.c:237
void point_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch, const struct volume *src_size, const struct pixel_format_desc *src_format, BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch, const struct volume *dst_size, const struct pixel_format_desc *dst_format, D3DCOLOR color_key, const PALETTEENTRY *palette)
Definition: surface.c:1735
HRESULT WINAPI D3DXGetImageInfoFromFileInMemory(const void *data, UINT datasize, D3DXIMAGE_INFO *info)
Definition: surface.c:875
LONG bottom
Definition: windef.h:299
void(* from_rgba)(const struct vec4 *src, struct vec4 *dst)
Definition: d3dx9_private.h:68
static void get_relevant_argb_components(const struct argb_conversion_info *info, const BYTE *col, DWORD *out)
Definition: surface.c:1473
char * cleanup(char *str)
Definition: wpickclick.c:99
DWORD depth
Definition: surface.c:138
const struct pixel_format_desc * get_format_info(D3DFORMAT format) DECLSPEC_HIDDEN
Definition: util.c:213
DWORD bpp
Definition: surface.c:181
#define DDS_CAPS2_CUBEMAP
Definition: surface.c:96
HRESULT load_cube_texture_from_dds(IDirect3DCubeTexture9 *cube_texture, const void *src_data, const PALETTEENTRY *palette, DWORD filter, DWORD color_key, const D3DXIMAGE_INFO *src_info)
Definition: surface.c:684
static HRESULT d3dformat_to_dds_pixel_format(struct dds_pixel_format *pixel_format, D3DFORMAT d3dformat)
Definition: surface.c:308
const struct pixel_format_desc * destformat
Definition: surface.c:1433
static void format_to_vec4(const struct pixel_format_desc *format, const BYTE *src, struct vec4 *dst)
Definition: surface.c:1521
#define IDirect3DSurface9_LockRect(p, a, b, c)
Definition: d3d9.h:635
BOOL wined3d_dxt5_decode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out, enum wined3d_format_id format, unsigned int w, unsigned int h)
Definition: dxtn.c:369
#define DDS_CAPS2_CUBEMAP_POSITIVEX
Definition: surface.c:97
#define RT_BITMAP
Definition: pedump.c:364
static HRESULT save_dds_surface_to_memory(ID3DXBuffer **dst_buffer, IDirect3DSurface9 *src_surface, const RECT *src_rect)
Definition: surface.c:478
DWORD caps
Definition: surface.c:142
#define UnmapViewOfFile
Definition: compat.h:403
#define D3DLOCK_READONLY
Definition: d3d8types.h:69
static const char stream_data[]
Definition: mlang.c:2324
INT INT y
Definition: msvc.h:62
#define memset(x, y, z)
Definition: compat.h:39
#define MAKEFOURCC(ch0, ch1, ch2, ch3)
Definition: dmdls.h:24
void(* to_rgba)(const struct vec4 *src, struct vec4 *dst, const PALETTEENTRY *palette)
Definition: d3dx9_private.h:69
HRESULT WINAPI D3DXGetImageInfoFromResourceW(HMODULE module, const WCHAR *resource, D3DXIMAGE_INFO *info)
Definition: surface.c:1099
UINT32 WICColor
Definition: wincodec.idl:250
HRESULT WINAPI D3DXSaveSurfaceToFileW(const WCHAR *dst_filename, D3DXIMAGE_FILEFORMAT file_format, IDirect3DSurface9 *src_surface, const PALETTEENTRY *src_palette, const RECT *src_rect)
Definition: surface.c:2150
void copy_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch, BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch, const struct volume *size, const struct pixel_format_desc *format)
Definition: surface.c:1601
#define BOOL
Definition: msvc.h:23
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glext.h:7005
static BOOL convert_dib_to_bmp(void **data, UINT *size)
Definition: surface.c:789
#define HeapFree(x, y, z)
Definition: compat.h:394
static DWORD make_argb_color(const struct argb_conversion_info *info, const DWORD *in)
Definition: surface.c:1503
HRESULT WINAPI D3DXCreateBuffer(DWORD size, ID3DXBuffer **buffer)
Definition: core.c:129
struct CFHEADER header
Definition: fdi.c:109
#define ID3DXBuffer_GetBufferPointer(p)
Definition: d3dx9core.h:85
enum _D3DRESOURCETYPE D3DRESOURCETYPE
GLenum GLuint GLint GLenum face
Definition: glext.h:7025
HRESULT WINAPI D3DXLoadSurfaceFromFileInMemory(IDirect3DSurface9 *pDestSurface, const PALETTEENTRY *pDestPalette, const RECT *pDestRect, const void *pSrcData, UINT SrcDataSize, const RECT *pSrcRect, DWORD dwFilter, D3DCOLOR Colorkey, D3DXIMAGE_INFO *pSrcInfo)
Definition: surface.c:1141
#define DDS_PF_ALPHA_ONLY
Definition: surface.c:110
#define file_size(inode)
Definition: reiserfs_fs.h:1869
#define SUCCEEDED(hr)
Definition: intsafe.h:57
struct png_info_def *typedef unsigned char **typedef struct png_info_def *typedef struct png_info_def *typedef struct png_info_def *typedef unsigned char ** row
Definition: typeof.h:76
INT x
Definition: msvc.h:62
Definition: fci.c:126
HRESULT load_volume_from_dds(IDirect3DVolume9 *dst_volume, const PALETTEENTRY *dst_palette, const D3DBOX *dst_box, const void *src_data, const D3DBOX *src_box, DWORD filter, D3DCOLOR color_key, const D3DXIMAGE_INFO *src_info)
Definition: surface.c:609