Henri Verbeet a écrit :
2008/8/29 Jérôme Gardou <[EMAIL PROTECTED]>:
If you want, I have an implementation of this same function for png... This
one is not commented at all, and need some rework. Get it for comparison.
As you said, it needs some cleanup etc, but at least it doesn't look
fundamentally broken to me. I'm not quite sure what the decompression
stuff in D3DXGetImageInfoFromFileW() is supposed to do though.
Here is a new one, slightly cleaned up and without this crappy
decompression stuff.
>From 6f0cfa7ddcc061aa9eda228ca8e01ab8961e182e Mon Sep 17 00:00:00 2001
From: =?utf-8?q?J=C3=A9r=C3=B4me=20Gardou?= <[EMAIL PROTECTED](none)>
Date: Fri, 29 Aug 2008 15:15:22 +0200
Subject: Implements D3DXGetImageInfoFromFile in d3dx9
---
dlls/d3dx9_36/Makefile.in | 5 +-
dlls/d3dx9_36/d3dx9_36.spec | 6 +-
dlls/d3dx9_36/d3dx9_36_private.h | 10 ++
dlls/d3dx9_36/texture.c | 196 ++++++++++++++++++++++++++++++++++++++
dlls/d3dx9_36/utils.c | 104 ++++++++++++++++++++
include/d3dx9tex.h | 2 +
6 files changed, 319 insertions(+), 4 deletions(-)
create mode 100644 dlls/d3dx9_36/texture.c
create mode 100644 dlls/d3dx9_36/utils.c
diff --git a/dlls/d3dx9_36/Makefile.in b/dlls/d3dx9_36/Makefile.in
index 0b5a3d3..0ce6bb4 100644
--- a/dlls/d3dx9_36/Makefile.in
+++ b/dlls/d3dx9_36/Makefile.in
@@ -5,13 +5,16 @@ VPATH = @srcdir@
MODULE = d3dx9_36.dll
IMPORTLIB = d3dx9
IMPORTS = d3d9 d3dx8 kernel32
+EXTRALIBS="-lpng"
C_SRCS = \
d3dx9_36_main.c \
font.c \
math.c \
shader.c \
- sprite.c
+ sprite.c \
+ texture.c \
+ utils.c
RC_SRCS = version.rc
diff --git a/dlls/d3dx9_36/d3dx9_36.spec b/dlls/d3dx9_36/d3dx9_36.spec
index a2dab96..f161c28 100644
--- a/dlls/d3dx9_36/d3dx9_36.spec
+++ b/dlls/d3dx9_36/d3dx9_36.spec
@@ -151,9 +151,9 @@
@ stub D3DXGetDeclVertexSize
@ stdcall D3DXGetDriverLevel(ptr)
@ stdcall D3DXGetFVFVertexSize(long) d3dx8.D3DXGetFVFVertexSize
-@ stdcall D3DXGetImageInfoFromFileA(ptr ptr) d3dx8.D3DXGetImageInfoFromFileA
-@ stdcall D3DXGetImageInfoFromFileInMemory(ptr long ptr) d3dx8.D3DXGetImageInfoFromFileInMemory
-@ stdcall D3DXGetImageInfoFromFileW(ptr ptr) d3dx8.D3DXGetImageInfoFromFileW
+@ stdcall D3DXGetImageInfoFromFileA(ptr ptr)
+@ stdcall D3DXGetImageInfoFromFileInMemory(ptr long ptr)
+@ stdcall D3DXGetImageInfoFromFileW(ptr ptr)
@ stdcall D3DXGetImageInfoFromResourceA(long ptr ptr) d3dx8.D3DXGetImageInfoFromResourceA
@ stdcall D3DXGetImageInfoFromResourceW(long ptr ptr) d3dx8.D3DXGetImageInfoFromResourceW
@ stdcall D3DXGetPixelShaderProfile(ptr)
diff --git a/dlls/d3dx9_36/d3dx9_36_private.h b/dlls/d3dx9_36/d3dx9_36_private.h
index e1c266d..17b49c1 100644
--- a/dlls/d3dx9_36/d3dx9_36_private.h
+++ b/dlls/d3dx9_36/d3dx9_36_private.h
@@ -45,5 +45,15 @@ typedef struct ID3DXSpriteImpl
/* ID3DXSprite fields */
} ID3DXSpriteImpl;
+/*Debugging utilities*/
+const char* debug_d3dformat(D3DFORMAT) ;
+const char* debug_d3dxfileformat(D3DXIMAGE_FILEFORMAT fmt) ;
+
+typedef struct file_in_memory
+{
+ BYTE* data ;
+ LONG offset ;
+ UINT length ;
+} file_in_memory;
#endif /* __WINE_D3DX9_36_PRIVATE_H */
diff --git a/dlls/d3dx9_36/texture.c b/dlls/d3dx9_36/texture.c
new file mode 100644
index 0000000..0a5bd21
--- /dev/null
+++ b/dlls/d3dx9_36/texture.c
@@ -0,0 +1,196 @@
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#include "config.h"
+#include "wine/port.h"
+#ifdef HAVE_PNG_H
+#include <png.h>
+#endif
+#include "wine/debug.h"
+#include "d3dx9_36_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
+
+/*This ones are needed by libpng and libjpeg to simulate file reading when dealing with memory
+and errors*/
+static void intern_read_from_memory(file_in_memory* file, void* data, UINT length)
+{
+ CopyMemory( data, file->data + file->offset, length) ;
+ file->offset += length ;
+ return ;
+}
+#ifdef HAVE_PNG_H
+static void png_read_from_mem (png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ intern_read_from_memory((file_in_memory*) png_get_io_ptr(png_ptr), (void*) data, (UINT) length) ;
+ return ;
+}
+
+static void png_error_fn(png_structp png_ptr, png_const_charp error_msg)
+{
+ ERR("png error : %p, %s", (void*)png_get_error_ptr(png_ptr), error_msg) ;
+}
+
+static void png_warning_fn(png_structp png_ptr, png_const_charp error_msg)
+{
+ WARN("png warning : %p, %s", (void*)png_get_error_ptr(png_ptr), error_msg) ;
+}
+#endif
+
+HRESULT WINAPI D3DXGetImageInfoFromFileInMemory( LPCVOID pSrcData, UINT SrcDataSize, D3DXIMAGE_INFO * pSrcInfo )
+{
+ TRACE("File is %p, size is %d, filling info %p\n", pSrcData, SrcDataSize, pSrcInfo) ;
+
+ file_in_memory* This = HeapAlloc(GetProcessHeap(), 0, sizeof(file_in_memory)) ;
+ This->data = pSrcData ;
+ This->offset=0 ;
+ This->length = SrcDataSize ;
+#ifdef HAVE_PNG_H
+ if(png_check_sig(pSrcData, 8))
+ {
+ /*Initializing libpng*/
+ png_structp png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, (png_voidp *)This, png_error_fn, png_warning_fn);
+ png_infop info_ptr = png_create_info_struct (png_ptr);
+ INT color_type, channels, bit_depth ;
+ png_set_read_fn (png_ptr, (png_voidp *)This, png_read_from_mem);
+ png_read_info(png_ptr, info_ptr) ;
+
+ /*Filling pSrcInfo*/
+ pSrcInfo->Width = info_ptr->width ;
+ pSrcInfo->Height = info_ptr->height ;
+ pSrcInfo->ResourceType = D3DRTYPE_TEXTURE ; /*FIXME : Volume, cube ?*/
+ pSrcInfo->MipLevels = 0 ;
+ pSrcInfo->ImageFileFormat = D3DXIFF_PNG ;
+ color_type = png_get_color_type(png_ptr, info_ptr) ;
+ channels = png_get_channels(png_ptr, info_ptr) ;
+ bit_depth = png_get_bit_depth(png_ptr, info_ptr) ;
+ pSrcInfo->Depth = bit_depth*channels ;
+ switch(color_type) {
+ case PNG_COLOR_TYPE_GRAY :
+ if(bit_depth <= 8)
+ pSrcInfo->Format = D3DFMT_L8 ; /*NOTE: will use png_set_gray_1_2_4_to_8 if <8?*/
+ else if (bit_depth == 16)
+ pSrcInfo->Format = D3DFMT_L16 ;
+ else
+ pSrcInfo->Format = D3DFMT_UNKNOWN ;
+ break ; /*PNG_COLOR_TYPE_GRAY */
+ case PNG_COLOR_TYPE_GRAY_ALPHA :
+ switch (bit_depth) {
+ case 4 :
+ pSrcInfo->Format = D3DFMT_A4L4 ;
+ break ;
+ case 8 :
+ pSrcInfo->Format = D3DFMT_A8L8 ;
+ break ;
+ default :
+ pSrcInfo->Format = D3DFMT_UNKNOWN ;
+ break ;
+ }
+ break ; /*PNG_COLOR_TYPE_GRAY_ALPHA*/
+ case PNG_COLOR_TYPE_PALETTE :
+ switch (bit_depth) {
+ case 8 :
+ pSrcInfo->Format = D3DFMT_P8 ;
+ break ;
+ default :
+ pSrcInfo->Format = D3DFMT_UNKNOWN ;
+ break ;
+ }
+ break ; /*COLOR_TYPE_PALETTE*/
+ case PNG_COLOR_TYPE_RGB :
+ if(channels == 3) {
+ switch (bit_depth) {
+ case 8 :
+ pSrcInfo->Format = D3DFMT_R8G8B8 ;
+ break ;
+ default :
+ pSrcInfo->Format = D3DFMT_UNKNOWN ;
+ break ;
+ }
+ } else if (channels == 4) {
+ switch (bit_depth) {
+ case 8 :
+ pSrcInfo->Format = D3DFMT_X8R8G8B8 ;
+ break ;
+ default :
+ pSrcInfo->Format = D3DFMT_UNKNOWN ;
+ break ;
+ }
+ }
+ break ; /*COLOR_TYPE_RGB*/
+ case PNG_COLOR_TYPE_RGBA :
+ switch (bit_depth) {
+ case 8 :
+ pSrcInfo->Format = D3DFMT_A8R8G8B8 ;
+ break ;
+ case 16 :
+ pSrcInfo->Format = D3DFMT_A16B16G16R16 ;
+ default :
+ pSrcInfo->Format = D3DFMT_UNKNOWN ;
+ break ;
+ }
+ break ; /*RGBA*/
+ }
+ /*Cleanup*/
+ png_read_end (png_ptr, NULL);
+ png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
+ HeapFree(GetProcessHeap(), 0, This) ;
+
+ TRACE("Format is %s, fileformat is %s, width is %d, height is %d, Depth is %d\n", debug_d3dformat(pSrcInfo->Format),
+ debug_d3dxfileformat(pSrcInfo->ImageFileFormat), pSrcInfo->Width, pSrcInfo->Height, pSrcInfo->Depth) ;
+ return D3D_OK ;
+ }
+#endif
+ FIXME("Unsupported file format. Make sure wine is compiled with support for it") ;
+ HeapFree(GetProcessHeap(), 0, This) ;
+ return D3DERR_INVALIDCALL ;
+}
+
+HRESULT WINAPI D3DXGetImageInfoFromFileA( LPCSTR pSrcFile, D3DXIMAGE_INFO * pSrcInfo )
+{
+ HANDLE res;
+ LPWSTR u_name;
+
+ if (!HIWORD(pSrcFile))
+ return D3DXGetImageInfoFromFileW((LPCWSTR)pSrcFile, pSrcInfo);
+
+ DWORD len = MultiByteToWideChar( CP_ACP, 0, pSrcFile, -1, NULL, 0 );
+ u_name = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+ MultiByteToWideChar( CP_ACP, 0, pSrcFile, -1, u_name, len );
+
+ res = D3DXGetImageInfoFromFileW(u_name, pSrcInfo);
+ HeapFree(GetProcessHeap(), 0, u_name);
+ return res;
+}
+
+HRESULT WINAPI D3DXGetImageInfoFromFileW( LPCWSTR pSrcFile, D3DXIMAGE_INFO * pSrcInfo )
+{
+ HRESULT ret ;
+ HANDLE This = CreateFileW(pSrcFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL) ;
+ if (This == HANDLE_INVALID_VALUE)
+ return D3DERR_INVALIDCALL ;
+
+ DWORD size = GetFileSize(This, NULL) ;
+ LPVOID Buffer = HeapAlloc( GetProcessHeap(), 0, size) ;
+ DWORD ReadSize = 0 ;
+ if (ReadFile(This, Buffer, size, &ReadSize, NULL) == 0)
+ return D3DERR_INVALIDCALL ;
+ if (ReadSize != size)
+ return D3DERR_INVALIDCALL ;
+ TRACE("%s, forwarding to D3DXGetImageInfoFromFileInMemory", debugstr_w(pSrcFile)) ;
+ ret = D3DXGetImageInfoFromFileInMemory( Buffer, size, pSrcInfo ) ;
+ HeapFree(GetProcessHeap(), 0, Buffer) ;
+ return ret ;
+}
diff --git a/dlls/d3dx9_36/utils.c b/dlls/d3dx9_36/utils.c
new file mode 100644
index 0000000..d6d4ed1
--- /dev/null
+++ b/dlls/d3dx9_36/utils.c
@@ -0,0 +1,104 @@
+#include "wine/debug.h"
+#include "d3dx9_36_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3dx) ;
+
+const char* debug_d3dformat(D3DFORMAT fmt) {
+ switch (fmt) {
+#define FMT_TO_STR(fmt) case fmt: return #fmt
+ FMT_TO_STR(D3DFMT_UNKNOWN);
+ FMT_TO_STR(D3DFMT_R8G8B8);
+ FMT_TO_STR(D3DFMT_A8R8G8B8);
+ FMT_TO_STR(D3DFMT_X8R8G8B8);
+ FMT_TO_STR(D3DFMT_R5G6B5);
+ FMT_TO_STR(D3DFMT_X1R5G5B5);
+ FMT_TO_STR(D3DFMT_A1R5G5B5);
+ FMT_TO_STR(D3DFMT_A4R4G4B4);
+ FMT_TO_STR(D3DFMT_R3G3B2);
+ FMT_TO_STR(D3DFMT_A8);
+ FMT_TO_STR(D3DFMT_A8R3G3B2);
+ FMT_TO_STR(D3DFMT_X4R4G4B4);
+ FMT_TO_STR(D3DFMT_A2B10G10R10);
+ FMT_TO_STR(D3DFMT_A8B8G8R8);
+ FMT_TO_STR(D3DFMT_X8B8G8R8);
+ FMT_TO_STR(D3DFMT_G16R16);
+ FMT_TO_STR(D3DFMT_A2R10G10B10);
+ FMT_TO_STR(D3DFMT_A16B16G16R16);
+ FMT_TO_STR(D3DFMT_A8P8);
+ FMT_TO_STR(D3DFMT_P8);
+ FMT_TO_STR(D3DFMT_L8);
+ FMT_TO_STR(D3DFMT_A8L8);
+ FMT_TO_STR(D3DFMT_A4L4);
+ FMT_TO_STR(D3DFMT_V8U8);
+ FMT_TO_STR(D3DFMT_L6V5U5);
+ FMT_TO_STR(D3DFMT_X8L8V8U8);
+ FMT_TO_STR(D3DFMT_Q8W8V8U8);
+ FMT_TO_STR(D3DFMT_V16U16);
+ FMT_TO_STR(D3DFMT_A2W10V10U10);
+ FMT_TO_STR(D3DFMT_UYVY);
+ FMT_TO_STR(D3DFMT_YUY2);
+ FMT_TO_STR(D3DFMT_DXT1);
+ FMT_TO_STR(D3DFMT_DXT2);
+ FMT_TO_STR(D3DFMT_DXT3);
+ FMT_TO_STR(D3DFMT_DXT4);
+ FMT_TO_STR(D3DFMT_DXT5);
+ FMT_TO_STR(D3DFMT_MULTI2_ARGB8);
+ FMT_TO_STR(D3DFMT_G8R8_G8B8);
+ FMT_TO_STR(D3DFMT_R8G8_B8G8);
+ FMT_TO_STR(D3DFMT_D16_LOCKABLE);
+ FMT_TO_STR(D3DFMT_D32);
+ FMT_TO_STR(D3DFMT_D15S1);
+ FMT_TO_STR(D3DFMT_D24S8);
+ FMT_TO_STR(D3DFMT_D24X8);
+ FMT_TO_STR(D3DFMT_D24X4S4);
+ FMT_TO_STR(D3DFMT_D16);
+ FMT_TO_STR(D3DFMT_L16);
+ FMT_TO_STR(D3DFMT_D32F_LOCKABLE);
+ FMT_TO_STR(D3DFMT_D24FS8);
+ FMT_TO_STR(D3DFMT_VERTEXDATA);
+ FMT_TO_STR(D3DFMT_INDEX16);
+ FMT_TO_STR(D3DFMT_INDEX32);
+ FMT_TO_STR(D3DFMT_Q16W16V16U16);
+ FMT_TO_STR(D3DFMT_R16F);
+ FMT_TO_STR(D3DFMT_G16R16F);
+ FMT_TO_STR(D3DFMT_A16B16G16R16F);
+ FMT_TO_STR(D3DFMT_R32F);
+ FMT_TO_STR(D3DFMT_G32R32F);
+ FMT_TO_STR(D3DFMT_A32B32G32R32F);
+ FMT_TO_STR(D3DFMT_CxV8U8);
+#undef FMT_TO_STR
+ default:
+ {
+ char fourcc[5];
+ fourcc[0] = (char)(fmt);
+ fourcc[1] = (char)(fmt >> 8);
+ fourcc[2] = (char)(fmt >> 16);
+ fourcc[3] = (char)(fmt >> 24);
+ fourcc[4] = 0;
+ if( isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]) )
+ FIXME("Unrecognized %u (as fourcc: %s) D3DFORMAT!\n", fmt, fourcc);
+ else
+ FIXME("Unrecognized %u D3DFORMAT!\n", fmt);
+ }
+ return "unrecognized";
+ }
+}
+
+const char* debug_d3dxfileformat(D3DXIMAGE_FILEFORMAT fmt)
+{
+#define FMT_TO_STR(fmt) case fmt: return #fmt
+ switch(fmt) {
+ FMT_TO_STR(D3DXIFF_BMP) ;
+ FMT_TO_STR(D3DXIFF_JPG) ;
+ FMT_TO_STR(D3DXIFF_TGA) ;
+ FMT_TO_STR(D3DXIFF_PNG) ;
+ FMT_TO_STR(D3DXIFF_DDS) ;
+ FMT_TO_STR(D3DXIFF_PPM) ;
+ FMT_TO_STR(D3DXIFF_HDR) ;
+ FMT_TO_STR(D3DXIFF_PFM) ;
+#undef FMT_TO_STR
+ default :
+ FIXME ("Unrecognized D3DXIMAGE_FILEFORMAT %u !\n", fmt) ;
+ return "unrecognized" ;
+ }
+}
\ No newline at end of file
diff --git a/include/d3dx9tex.h b/include/d3dx9tex.h
index 8e553e0..8073ab8 100644
--- a/include/d3dx9tex.h
+++ b/include/d3dx9tex.h
@@ -63,6 +63,8 @@ typedef enum _D3DXIMAGE_FILEFORMAT
D3DXIFF_DDS,
D3DXIFF_PPM,
D3DXIFF_DIB,
+ D3DXIFF_HDR,
+ D3DXIFF_PFM,
D3DXIFF_FORCE_DWORD = 0x7fffffff
} D3DXIMAGE_FILEFORMAT;
--
1.5.4.3