windowscodecs: Start loading PNG in unix lib.
Signed-off-by: Esme Povirk <esme@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
0f61ed18ef
commit
6aa8e17975
|
@ -42,6 +42,67 @@ WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
|
||||||
|
|
||||||
#ifdef SONAME_LIBPNG
|
#ifdef SONAME_LIBPNG
|
||||||
|
|
||||||
|
#include <png.h>
|
||||||
|
|
||||||
|
static void *libpng_handle;
|
||||||
|
#define MAKE_FUNCPTR(f) static typeof(f) * p##f
|
||||||
|
MAKE_FUNCPTR(png_create_info_struct);
|
||||||
|
MAKE_FUNCPTR(png_create_read_struct);
|
||||||
|
MAKE_FUNCPTR(png_destroy_read_struct);
|
||||||
|
MAKE_FUNCPTR(png_error);
|
||||||
|
MAKE_FUNCPTR(png_get_error_ptr);
|
||||||
|
MAKE_FUNCPTR(png_get_io_ptr);
|
||||||
|
MAKE_FUNCPTR(png_read_info);
|
||||||
|
MAKE_FUNCPTR(png_set_crc_action);
|
||||||
|
MAKE_FUNCPTR(png_set_error_fn);
|
||||||
|
MAKE_FUNCPTR(png_set_read_fn);
|
||||||
|
#undef MAKE_FUNCPTR
|
||||||
|
|
||||||
|
static CRITICAL_SECTION init_png_cs;
|
||||||
|
static CRITICAL_SECTION_DEBUG init_png_cs_debug =
|
||||||
|
{
|
||||||
|
0, 0, &init_png_cs,
|
||||||
|
{ &init_png_cs_debug.ProcessLocksList,
|
||||||
|
&init_png_cs_debug.ProcessLocksList },
|
||||||
|
0, 0, { (DWORD_PTR)(__FILE__ ": init_png_cs") }
|
||||||
|
};
|
||||||
|
static CRITICAL_SECTION init_png_cs = { &init_png_cs_debug, -1, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
static void *load_libpng(void)
|
||||||
|
{
|
||||||
|
void *result;
|
||||||
|
|
||||||
|
RtlEnterCriticalSection(&init_png_cs);
|
||||||
|
|
||||||
|
if(!libpng_handle && (libpng_handle = dlopen(SONAME_LIBPNG, RTLD_NOW)) != NULL) {
|
||||||
|
|
||||||
|
#define LOAD_FUNCPTR(f) \
|
||||||
|
if((p##f = dlsym(libpng_handle, #f)) == NULL) { \
|
||||||
|
libpng_handle = NULL; \
|
||||||
|
RtlLeaveCriticalSection(&init_png_cs); \
|
||||||
|
return NULL; \
|
||||||
|
}
|
||||||
|
LOAD_FUNCPTR(png_create_info_struct);
|
||||||
|
LOAD_FUNCPTR(png_create_read_struct);
|
||||||
|
LOAD_FUNCPTR(png_destroy_read_struct);
|
||||||
|
LOAD_FUNCPTR(png_error);
|
||||||
|
LOAD_FUNCPTR(png_get_error_ptr);
|
||||||
|
LOAD_FUNCPTR(png_get_io_ptr);
|
||||||
|
LOAD_FUNCPTR(png_read_info);
|
||||||
|
LOAD_FUNCPTR(png_set_crc_action);
|
||||||
|
LOAD_FUNCPTR(png_set_error_fn);
|
||||||
|
LOAD_FUNCPTR(png_set_read_fn);
|
||||||
|
|
||||||
|
#undef LOAD_FUNCPTR
|
||||||
|
}
|
||||||
|
|
||||||
|
result = libpng_handle;
|
||||||
|
|
||||||
|
RtlLeaveCriticalSection(&init_png_cs);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
struct png_decoder
|
struct png_decoder
|
||||||
{
|
{
|
||||||
struct decoder decoder;
|
struct decoder decoder;
|
||||||
|
@ -52,6 +113,97 @@ static inline struct png_decoder *impl_from_decoder(struct decoder* iface)
|
||||||
return CONTAINING_RECORD(iface, struct png_decoder, decoder);
|
return CONTAINING_RECORD(iface, struct png_decoder, decoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void user_error_fn(png_structp png_ptr, png_const_charp error_message)
|
||||||
|
{
|
||||||
|
jmp_buf *pjmpbuf;
|
||||||
|
|
||||||
|
/* This uses setjmp/longjmp just like the default. We can't use the
|
||||||
|
* default because there's no way to access the jmp buffer in the png_struct
|
||||||
|
* that works in 1.2 and 1.4 and allows us to dynamically load libpng. */
|
||||||
|
WARN("PNG error: %s\n", debugstr_a(error_message));
|
||||||
|
pjmpbuf = ppng_get_error_ptr(png_ptr);
|
||||||
|
longjmp(*pjmpbuf, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void user_warning_fn(png_structp png_ptr, png_const_charp warning_message)
|
||||||
|
{
|
||||||
|
WARN("PNG warning: %s\n", debugstr_a(warning_message));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
|
||||||
|
{
|
||||||
|
IStream *stream = ppng_get_io_ptr(png_ptr);
|
||||||
|
HRESULT hr;
|
||||||
|
ULONG bytesread;
|
||||||
|
|
||||||
|
hr = stream_read(stream, data, length, &bytesread);
|
||||||
|
if (FAILED(hr) || bytesread != length)
|
||||||
|
{
|
||||||
|
ppng_error(png_ptr, "failed reading data");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CDECL png_decoder_initialize(struct decoder *iface, IStream *stream, struct decoder_stat *st)
|
||||||
|
{
|
||||||
|
png_structp png_ptr;
|
||||||
|
png_infop info_ptr;
|
||||||
|
png_infop end_info;
|
||||||
|
jmp_buf jmpbuf;
|
||||||
|
HRESULT hr = E_FAIL;
|
||||||
|
|
||||||
|
png_ptr = ppng_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||||
|
if (!png_ptr)
|
||||||
|
{
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
info_ptr = ppng_create_info_struct(png_ptr);
|
||||||
|
if (!info_ptr)
|
||||||
|
{
|
||||||
|
ppng_destroy_read_struct(&png_ptr, NULL, NULL);
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
end_info = ppng_create_info_struct(png_ptr);
|
||||||
|
if (!end_info)
|
||||||
|
{
|
||||||
|
ppng_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set up setjmp/longjmp error handling */
|
||||||
|
if (setjmp(jmpbuf))
|
||||||
|
{
|
||||||
|
hr = WINCODEC_ERR_UNKNOWNIMAGEFORMAT;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
ppng_set_error_fn(png_ptr, jmpbuf, user_error_fn, user_warning_fn);
|
||||||
|
ppng_set_crc_action(png_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE);
|
||||||
|
|
||||||
|
/* seek to the start of the stream */
|
||||||
|
hr = stream_seek(stream, 0, STREAM_SEEK_SET, NULL);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set up custom i/o handling */
|
||||||
|
ppng_set_read_fn(png_ptr, stream, user_read_data);
|
||||||
|
|
||||||
|
/* read the header */
|
||||||
|
ppng_read_info(png_ptr, info_ptr);
|
||||||
|
|
||||||
|
st->flags = WICBitmapDecoderCapabilityCanDecodeAllImages |
|
||||||
|
WICBitmapDecoderCapabilityCanDecodeSomeImages |
|
||||||
|
WICBitmapDecoderCapabilityCanEnumerateMetadata;
|
||||||
|
st->frame_count = 1;
|
||||||
|
hr = S_OK;
|
||||||
|
|
||||||
|
end:
|
||||||
|
ppng_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
void CDECL png_decoder_destroy(struct decoder* iface)
|
void CDECL png_decoder_destroy(struct decoder* iface)
|
||||||
{
|
{
|
||||||
struct png_decoder *This = impl_from_decoder(iface);
|
struct png_decoder *This = impl_from_decoder(iface);
|
||||||
|
@ -60,6 +212,7 @@ void CDECL png_decoder_destroy(struct decoder* iface)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct decoder_funcs png_decoder_vtable = {
|
static const struct decoder_funcs png_decoder_vtable = {
|
||||||
|
png_decoder_initialize,
|
||||||
png_decoder_destroy
|
png_decoder_destroy
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -67,7 +220,11 @@ HRESULT CDECL png_decoder_create(struct decoder_info *info, struct decoder **res
|
||||||
{
|
{
|
||||||
struct png_decoder *This;
|
struct png_decoder *This;
|
||||||
|
|
||||||
TRACE("\n");
|
if (!load_libpng())
|
||||||
|
{
|
||||||
|
ERR("Failed reading PNG because unable to find %s\n",SONAME_LIBPNG);
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
This = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(*This));
|
This = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(*This));
|
||||||
|
|
||||||
|
|
|
@ -255,6 +255,25 @@ HRESULT write_source(IWICBitmapFrameEncode *iface,
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT CDECL stream_read(IStream *stream, void *buffer, ULONG read, ULONG *bytes_read)
|
||||||
|
{
|
||||||
|
return IStream_Read(stream, buffer, read, bytes_read);
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CDECL stream_seek(IStream *stream, LONGLONG ofs, DWORD origin, ULONGLONG *new_position)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
LARGE_INTEGER ofs_large;
|
||||||
|
ULARGE_INTEGER pos_large;
|
||||||
|
|
||||||
|
ofs_large.QuadPart = ofs;
|
||||||
|
hr = IStream_Seek(stream, ofs_large, origin, &pos_large);
|
||||||
|
if (new_position)
|
||||||
|
*new_position = pos_large.QuadPart;
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
void reverse_bgr8(UINT bytesperpixel, LPBYTE bits, UINT width, UINT height, INT stride)
|
void reverse_bgr8(UINT bytesperpixel, LPBYTE bits, UINT width, UINT height, INT stride)
|
||||||
{
|
{
|
||||||
UINT x, y;
|
UINT x, y;
|
||||||
|
|
|
@ -446,6 +446,7 @@ typedef struct {
|
||||||
IStream *stream;
|
IStream *stream;
|
||||||
struct decoder *png_decoder;
|
struct decoder *png_decoder;
|
||||||
struct decoder_info decoder_info;
|
struct decoder_info decoder_info;
|
||||||
|
struct decoder_stat file_info;
|
||||||
png_structp png_ptr;
|
png_structp png_ptr;
|
||||||
png_infop info_ptr;
|
png_infop info_ptr;
|
||||||
png_infop end_info;
|
png_infop end_info;
|
||||||
|
@ -543,6 +544,7 @@ static ULONG WINAPI PngDecoder_Release(IWICBitmapDecoder *iface)
|
||||||
static HRESULT WINAPI PngDecoder_QueryCapability(IWICBitmapDecoder *iface, IStream *stream,
|
static HRESULT WINAPI PngDecoder_QueryCapability(IWICBitmapDecoder *iface, IStream *stream,
|
||||||
DWORD *capability)
|
DWORD *capability)
|
||||||
{
|
{
|
||||||
|
PngDecoder *This = impl_from_IWICBitmapDecoder(iface);
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE("(%p,%p,%p)\n", iface, stream, capability);
|
TRACE("(%p,%p,%p)\n", iface, stream, capability);
|
||||||
|
@ -552,9 +554,7 @@ static HRESULT WINAPI PngDecoder_QueryCapability(IWICBitmapDecoder *iface, IStre
|
||||||
hr = IWICBitmapDecoder_Initialize(iface, stream, WICDecodeMetadataCacheOnDemand);
|
hr = IWICBitmapDecoder_Initialize(iface, stream, WICDecodeMetadataCacheOnDemand);
|
||||||
if (hr != S_OK) return hr;
|
if (hr != S_OK) return hr;
|
||||||
|
|
||||||
*capability = WICBitmapDecoderCapabilityCanDecodeAllImages |
|
*capability = (This->file_info.flags & DECODER_FLAGS_CAPABILITY_MASK);
|
||||||
WICBitmapDecoderCapabilityCanDecodeSomeImages;
|
|
||||||
/* FIXME: WICBitmapDecoderCapabilityCanEnumerateMetadata */
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -595,6 +595,16 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
|
||||||
|
|
||||||
EnterCriticalSection(&This->lock);
|
EnterCriticalSection(&This->lock);
|
||||||
|
|
||||||
|
if (This->initialized)
|
||||||
|
{
|
||||||
|
hr = WINCODEC_ERR_WRONGSTATE;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = decoder_initialize(This->png_decoder, pIStream, &This->file_info);
|
||||||
|
if (FAILED(hr))
|
||||||
|
goto end;
|
||||||
|
|
||||||
/* initialize libpng */
|
/* initialize libpng */
|
||||||
This->png_ptr = ppng_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
This->png_ptr = ppng_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||||
if (!This->png_ptr)
|
if (!This->png_ptr)
|
||||||
|
@ -896,9 +906,12 @@ static HRESULT WINAPI PngDecoder_GetThumbnail(IWICBitmapDecoder *iface,
|
||||||
static HRESULT WINAPI PngDecoder_GetFrameCount(IWICBitmapDecoder *iface,
|
static HRESULT WINAPI PngDecoder_GetFrameCount(IWICBitmapDecoder *iface,
|
||||||
UINT *pCount)
|
UINT *pCount)
|
||||||
{
|
{
|
||||||
|
PngDecoder *This = impl_from_IWICBitmapDecoder(iface);
|
||||||
if (!pCount) return E_INVALIDARG;
|
if (!pCount) return E_INVALIDARG;
|
||||||
|
|
||||||
*pCount = 1;
|
if (!This->initialized) return WINCODEC_ERR_WRONGSTATE;
|
||||||
|
|
||||||
|
*pCount = This->file_info.frame_count;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,9 +39,14 @@ static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT;
|
||||||
|
|
||||||
static const struct unix_funcs *unix_funcs;
|
static const struct unix_funcs *unix_funcs;
|
||||||
|
|
||||||
|
static const struct win32_funcs win32_funcs = {
|
||||||
|
stream_read,
|
||||||
|
stream_seek
|
||||||
|
};
|
||||||
|
|
||||||
static BOOL WINAPI load_unixlib( INIT_ONCE *once, void *param, void **context )
|
static BOOL WINAPI load_unixlib( INIT_ONCE *once, void *param, void **context )
|
||||||
{
|
{
|
||||||
__wine_init_unix_lib( windowscodecs_module, DLL_PROCESS_ATTACH, NULL, &unix_funcs );
|
__wine_init_unix_lib( windowscodecs_module, DLL_PROCESS_ATTACH, &win32_funcs, &unix_funcs );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,6 +66,12 @@ static inline struct decoder_wrapper *impl_from_decoder(struct decoder* iface)
|
||||||
return CONTAINING_RECORD(iface, struct decoder_wrapper, win32_decoder);
|
return CONTAINING_RECORD(iface, struct decoder_wrapper, win32_decoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT CDECL decoder_wrapper_initialize(struct decoder* iface, IStream* stream, struct decoder_stat *st)
|
||||||
|
{
|
||||||
|
struct decoder_wrapper* This = impl_from_decoder(iface);
|
||||||
|
return unix_funcs->decoder_initialize(This->unix_decoder, stream, st);
|
||||||
|
}
|
||||||
|
|
||||||
void CDECL decoder_wrapper_destroy(struct decoder* iface)
|
void CDECL decoder_wrapper_destroy(struct decoder* iface)
|
||||||
{
|
{
|
||||||
struct decoder_wrapper* This = impl_from_decoder(iface);
|
struct decoder_wrapper* This = impl_from_decoder(iface);
|
||||||
|
@ -69,6 +80,7 @@ void CDECL decoder_wrapper_destroy(struct decoder* iface)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct decoder_funcs decoder_wrapper_vtable = {
|
static const struct decoder_funcs decoder_wrapper_vtable = {
|
||||||
|
decoder_wrapper_initialize,
|
||||||
decoder_wrapper_destroy
|
decoder_wrapper_destroy
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,18 @@
|
||||||
|
|
||||||
#include "wincodecs_common.h"
|
#include "wincodecs_common.h"
|
||||||
|
|
||||||
|
static const struct win32_funcs *win32_funcs;
|
||||||
|
|
||||||
|
HRESULT CDECL stream_read(IStream *stream, void *buffer, ULONG read, ULONG *bytes_read)
|
||||||
|
{
|
||||||
|
return win32_funcs->stream_read(stream, buffer, read, bytes_read);
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CDECL stream_seek(IStream *stream, LONGLONG ofs, DWORD origin, ULONGLONG *new_position)
|
||||||
|
{
|
||||||
|
return win32_funcs->stream_seek(stream, ofs, origin, new_position);
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT CDECL decoder_create(const CLSID *decoder_clsid, struct decoder_info *info, struct decoder **result)
|
HRESULT CDECL decoder_create(const CLSID *decoder_clsid, struct decoder_info *info, struct decoder **result)
|
||||||
{
|
{
|
||||||
if (IsEqualGUID(decoder_clsid, &CLSID_WICPngDecoder))
|
if (IsEqualGUID(decoder_clsid, &CLSID_WICPngDecoder))
|
||||||
|
@ -53,6 +65,7 @@ HRESULT CDECL decoder_create(const CLSID *decoder_clsid, struct decoder_info *in
|
||||||
|
|
||||||
static const struct unix_funcs unix_funcs = {
|
static const struct unix_funcs unix_funcs = {
|
||||||
decoder_create,
|
decoder_create,
|
||||||
|
decoder_initialize,
|
||||||
decoder_destroy
|
decoder_destroy
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -60,6 +73,8 @@ NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *p
|
||||||
{
|
{
|
||||||
if (reason != DLL_PROCESS_ATTACH) return STATUS_SUCCESS;
|
if (reason != DLL_PROCESS_ATTACH) return STATUS_SUCCESS;
|
||||||
|
|
||||||
|
win32_funcs = ptr_in;
|
||||||
|
|
||||||
*(const struct unix_funcs **)ptr_out = &unix_funcs;
|
*(const struct unix_funcs **)ptr_out = &unix_funcs;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,11 @@
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
HRESULT CDECL decoder_initialize(struct decoder *decoder, IStream *stream, struct decoder_stat *st)
|
||||||
|
{
|
||||||
|
return decoder->vtable->initialize(decoder, stream, st);
|
||||||
|
}
|
||||||
|
|
||||||
void CDECL decoder_destroy(struct decoder *decoder)
|
void CDECL decoder_destroy(struct decoder *decoder)
|
||||||
{
|
{
|
||||||
decoder->vtable->destroy(decoder);
|
decoder->vtable->destroy(decoder);
|
||||||
|
|
|
@ -259,6 +259,14 @@ struct decoder_info
|
||||||
CLSID clsid;
|
CLSID clsid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define DECODER_FLAGS_CAPABILITY_MASK 0x1f
|
||||||
|
|
||||||
|
struct decoder_stat
|
||||||
|
{
|
||||||
|
DWORD flags;
|
||||||
|
DWORD frame_count;
|
||||||
|
};
|
||||||
|
|
||||||
struct decoder
|
struct decoder
|
||||||
{
|
{
|
||||||
const struct decoder_funcs *vtable;
|
const struct decoder_funcs *vtable;
|
||||||
|
@ -266,10 +274,21 @@ struct decoder
|
||||||
|
|
||||||
struct decoder_funcs
|
struct decoder_funcs
|
||||||
{
|
{
|
||||||
|
HRESULT (CDECL *initialize)(struct decoder* This, IStream *stream, struct decoder_stat *st);
|
||||||
void (CDECL *destroy)(struct decoder* This);
|
void (CDECL *destroy)(struct decoder* This);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
HRESULT CDECL stream_read(IStream *stream, void *buffer, ULONG read, ULONG *bytes_read);
|
||||||
|
HRESULT CDECL stream_seek(IStream *stream, LONGLONG ofs, DWORD origin, ULONGLONG *new_position);
|
||||||
|
|
||||||
|
struct win32_funcs
|
||||||
|
{
|
||||||
|
HRESULT (CDECL *stream_read)(IStream *stream, void *buffer, ULONG read, ULONG *bytes_read);
|
||||||
|
HRESULT (CDECL *stream_seek)(IStream *stream, LONGLONG ofs, DWORD origin, ULONGLONG *new_position);
|
||||||
|
};
|
||||||
|
|
||||||
HRESULT CDECL decoder_create(const CLSID *decoder_clsid, struct decoder_info *info, struct decoder **result);
|
HRESULT CDECL decoder_create(const CLSID *decoder_clsid, struct decoder_info *info, struct decoder **result);
|
||||||
|
HRESULT CDECL decoder_initialize(struct decoder *This, IStream *stream, struct decoder_stat *st);
|
||||||
void CDECL decoder_destroy(struct decoder *This);
|
void CDECL decoder_destroy(struct decoder *This);
|
||||||
|
|
||||||
HRESULT CDECL png_decoder_create(struct decoder_info *info, struct decoder **result);
|
HRESULT CDECL png_decoder_create(struct decoder_info *info, struct decoder **result);
|
||||||
|
@ -277,6 +296,7 @@ HRESULT CDECL png_decoder_create(struct decoder_info *info, struct decoder **res
|
||||||
struct unix_funcs
|
struct unix_funcs
|
||||||
{
|
{
|
||||||
HRESULT (CDECL *decoder_create)(const CLSID *decoder_clsid, struct decoder_info *info, struct decoder **result);
|
HRESULT (CDECL *decoder_create)(const CLSID *decoder_clsid, struct decoder_info *info, struct decoder **result);
|
||||||
|
HRESULT (CDECL *decoder_initialize)(struct decoder *This, IStream *stream, struct decoder_stat *st);
|
||||||
void (CDECL *decoder_destroy)(struct decoder* This);
|
void (CDECL *decoder_destroy)(struct decoder* This);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue