I'm trying to implement the D3DXGetImageInfoFrom* functions in d3dx8/9 dlls, 
and I have a few questions.

As there is no related source file from this kind of functions, I created 
texture.c within dlls/d3dx8. I guess this is the way you want it, but I'd 
like to hear it from you. 

Then I need libpng to handle this. I know that gdi32 has some (limited) 
support for this files, but I wasn't able to know how it was included in its 
code. A simple #include <png.h> doesn't work, as I expected. So I would like 
to know how wine build process handle third party libraries.

Then, I'd like to know what you think about the code attached here. Please 
don't forget that this is the very first time I make some code for wine !

Cheers.
Jérôme
/*
 * Direct3D X 8 textures related functions
 *
 * Copyright (C) 2002 Raphael Junqueira
 *
 * 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"

#include <stdarg.h>

#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "wine/debug.h"

#include "d3d8.h"
#include "d3dx8_private.h"
#include "d3dx8tex.h"

WINE_DEFAULT_DEBUG_CHANNEL(d3d);

const char png_header[] = {137, 80, 78, 71, 13, 10, 26, 10} ;

static HRESULT Get_Info_from_BMP_In_Memory( LPCVOID pSrcData, D3DXIMAGE_INFO* pSrcInfo)
{
    BITMAPINFOHEADER* info_header = (BITMAPINFOHEADER*) pSrcData + sizeof(BITMAPFILEHEADER) ;
    pSrcInfo->Width = info_header->biWidth ;
    pSrcInfo->Height = info_header->biHeight ;
    pSrcInfo->Depth = info_header->biBitCount ;
    pSrcInfo->MipLevels = 0 ;
    pSrcInfo->ResourceType = D3DRTYPE_TEXTURE ;
    pSrcInfo->ImageFileFormat = D3DXIFF_BMP ;
    switch (pSrcInfo->Depth) {
        /*1 and 4 are unlikely to happen. Anyway, handle it as 8 bpp*/
        case 1 :
        case 4 :
        case 8 :
            pSrcInfo->Format = D3DFMT_P8 ;
        break ;
        case 16 :
            pSrcInfo->Format = D3DFMT_X1R5G5B5 ;
        break ;
        case 24 :
            pSrcInfo->Format = D3DFMT_R8G8B8 ;
        break ;
        case 32 :
            pSrcInfo->Format = D3DFMT_X8R8G8B8 ;
        break ;
    }
    return D3D_OK ;
}

#if 0

typedef struct _IN_MEMORY_PNG {
    LPCVOID data ;
    INT offset ;
} IN_MEMORY_PNG ;

static void read_png_file_from_memory(png_structp png_ptr, png_bytep data, png_size_t length)
{
    IN_MEMORY_PNG* src = (IN_MEMORY_PNG*) png_get_io_ptr(png_ptr) ;
    memcpy(data, src->data + src->offset, length) ;
    src->offset += length ;
}

static HRESULT Get_Info_From_PNG_In_Memory( LPCVOID pSrcData, D3DXIMAGE_INFO* pSrcInfo)
{
    IN_MEMORY_PNG This ;
    This.data = pSrcData ;
    This.offset = 0 ;
    /*If the png_* functions fail, then this is likely a bad call*/
    png_structp png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING,NULL,NULL,NULL) ;
    if(!png_ptr)
        return D3DERR_INVALIDCALL ;
    png_infop info_ptr = png_create_info_struct(png_ptr);
    if(!info_ptr) {
        png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
            return D3DERR_INVALIDCALL ;
        }
    if ( setjmp(png_ptr->jmpbuf) ) {
        png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
        return D3DERR_INVALIDCALL ;
    }

    pSrcInfo->ImageFileFormat = D3DXIFF_PNG ;
    pSrcInfo->ResourceType = D3DRTYPE_TEXTURE ;
    png_set_read_fn(png_ptr, (png_voidp*) &This, read_png_file_from_memory) ;
    png_read_info(png_ptr, info_ptr);
    pSrcInfo->Width = png_get_image_width(png_ptr, info_ptr) ;
    pSrcInfo->Height = png_get_image_height(png_ptr, png_info) ;
    pSrcInfo->Depth = png_get_bit_depth(png_ptr, png_info) ;
    pSrcInfo->MipLevels = 0 ;
    pSrcInfo->ResourceType = D3DRTYPE_TEXTURE ;
    pSrcInfo->ImageFileFormat = D3DXIFF_PNG ;
    switch (png_get_color_type(png_ptr, info_ptr)) {
        case PNG_COLOR_TYPE_GRAY :
            pSrcInfo->Format = D3DFMT_L8 ;
        break ;
        case PNG_COLOR_TYPE_GRAY_ALPHA :
            if (pSrcInfo->Depth == 8)
                pSrcInfo->Format = D3DFMT_A4L4 ;
            else
                pSrcInfo->Format = D3DFMT_A8L8 ;
        break ;
    }
    return D3D_OK ;
}
#else
static HRESULT Get_Info_From_PNG_In_Memory( LPCVOID pSrcData, D3DXIMAGE_INFO* pSrcInfo)
{
    FIXME("Wine Has been built without PNG support. Expect problems") ;
    return D3D_OK ;
}
#endif


/**GetImageInfoFromFileInMemory **/
/* Fills the D3DXIMAGE_INFO field from a file loaded in memory */

HRESULT WINAPI D3DXGetImageInfoFromFileInMemory( LPCVOID pSrcData, UINT SrcDataSize, D3DXIMAGE_INFO* pSrcInfo)
{
    TRACE("(%p),%d,%p", pSrcData, SrcDataSize, pSrcInfo) ;
    /*Here, we check both headers and size parameter. If inconsistent informations are given, then we return an invalid call*/
/*BMP files*/
    if (strncmp(pSrcData, "BM", 2) == 0 ){
        UINT* Size = (UINT*) pSrcData + 2 ;
        if (*Size != SrcDataSize)
            return D3DERR_INVALIDCALL ;
        else {
            return Get_Info_from_BMP_In_Memory(pSrcData, pSrcInfo) ;
        }
    }
/*PNG files*/
    if ( strncmp(pSrcData, png_header, 8) == 0 ) {
        /*FIXME : Check SrcDataSize*/
        return Get_Info_From_PNG_In_Memory(pSrcData, pSrcInfo) ;

    }
    return D3DERR_INVALIDCALL ;
}


Reply via email to