Jérôme Gardou a écrit :
Henri Verbeet a écrit :
2008/8/28 Jérôme Gardou <[EMAIL PROTECTED]>:
D3DX supports a wide range of file types for textures. Instead of
rewriting
everything from scratch, the best would certainly be to use some image
processing library to handle them. As a bonus, this would allow lighter
code.
I'm not sure it would be worth it. The only non-trivial formats I see
in D3DXIMAGE_FILEFORMAT are JPEG and PNG, and we already link to
libjpeg and libpng in other parts of Wine.
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.
With the patch...
>From 66126c6dd848f561a0c689b6582b83e9354269f9 Mon Sep 17 00:00:00 2001
From: Jérôme Gardou <[EMAIL PROTECTED]>
Date: Fri, 25 Jul 2008 02:23:54 +0200
Subject: Implements GetFileInfoFromFile* into d3dx9_* for png files
---
dlls/d3dx9_36/Makefile.in | 4 +-
dlls/d3dx9_36/d3dx9_36.spec | 6 +-
dlls/d3dx9_36/d3dx9_36_private.h | 7 ++
dlls/d3dx9_36/tests/Makefile.in | 3 +-
dlls/d3dx9_36/texture.c | 186 ++++++++++++++++++++++++++++++++++++++
5 files changed, 201 insertions(+), 5 deletions(-)
create mode 100644 dlls/d3dx9_36/texture.c
diff --git a/dlls/d3dx9_36/Makefile.in b/dlls/d3dx9_36/Makefile.in
index 78cfd97..0e34c39 100644
--- a/dlls/d3dx9_36/Makefile.in
+++ b/dlls/d3dx9_36/Makefile.in
@@ -5,12 +5,14 @@ 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
+ shader.c \
+ texture.c
RC_SRCS = version.rc
diff --git a/dlls/d3dx9_36/d3dx9_36.spec b/dlls/d3dx9_36/d3dx9_36.spec
index 1619f16..b11ce90 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
@ stub D3DXGetPixelShaderProfile
diff --git a/dlls/d3dx9_36/d3dx9_36_private.h b/dlls/d3dx9_36/d3dx9_36_private.h
index 33d83b2..d2b9c87 100644
--- a/dlls/d3dx9_36/d3dx9_36_private.h
+++ b/dlls/d3dx9_36/d3dx9_36_private.h
@@ -36,5 +36,12 @@ typedef struct ID3DXFontImpl
/* ID3DXFont fields */
} ID3DXFontImpl;
+typedef struct file_in_memory
+{
+ LPCVOID data ;
+ LONG offset ;
+ UINT length ;
+} file_in_memory;
+
#endif /* __WINE_D3DX9_36_PRIVATE_H */
diff --git a/dlls/d3dx9_36/tests/Makefile.in b/dlls/d3dx9_36/tests/Makefile.in
index 40500e2..25ab9ab 100644
--- a/dlls/d3dx9_36/tests/Makefile.in
+++ b/dlls/d3dx9_36/tests/Makefile.in
@@ -7,7 +7,8 @@ IMPORTS = d3dx9 kernel32
CTESTS = \
math.c \
- shader.c
+ shader.c \
+ texture.c
@MAKE_TEST_RULES@
diff --git a/dlls/d3dx9_36/texture.c b/dlls/d3dx9_36/texture.c
new file mode 100644
index 0000000..d7a9827
--- /dev/null
+++ b/dlls/d3dx9_36/texture.c
@@ -0,0 +1,186 @@
+/*
+ * 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 "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "winnls.h"
+#include "lzexpand.h"
+#include "d3dx9.h"
+#include "d3dx9_36_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
+
+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 )
+{
+ 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))
+ {
+ 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) ;
+ 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*/
+ }
+ png_read_end (png_ptr, NULL);
+ png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
+ 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 )
+{
+ LPOFSTRUCT fileofstruct = HeapAlloc(GetProcessHeap(), 0, sizeof(OFSTRUCT)) ;
+ HRESULT ret ;
+ INT This = LZOpenFileW(pSrcFile, fileofstruct, OF_READ) ;
+ INT size = LZSeek(This, 0, 2) ;
+ LZSeek(This, 0, 0) ;
+ LPCVOID Buffer = HeapAlloc(GetProcessHeap(), 0, size) ;
+ LZRead(This, (LPSTR)Buffer, size) ;
+ LZClose(This) ;
+ ret = D3DXGetImageInfoFromFileInMemory( Buffer, size, pSrcInfo ) ;
+ HeapFree(GetProcessHeap(), 0, Buffer) ;
+ HeapFree(GetProcessHeap(), 0, fileofstruct) ;
+ return ret ;
+}
--
1.5.5.2