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