windowscodecs: Use the unix library to find PNG metadata.
Signed-off-by: Esme Povirk <esme@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
53ce545e69
commit
70ea6485e8
|
@ -133,6 +133,7 @@ static void *load_libpng(void)
|
||||||
struct png_decoder
|
struct png_decoder
|
||||||
{
|
{
|
||||||
struct decoder decoder;
|
struct decoder decoder;
|
||||||
|
IStream *stream;
|
||||||
struct decoder_frame decoder_frame;
|
struct decoder_frame decoder_frame;
|
||||||
UINT stride;
|
UINT stride;
|
||||||
BYTE *image_bits;
|
BYTE *image_bits;
|
||||||
|
@ -425,6 +426,8 @@ HRESULT CDECL png_decoder_initialize(struct decoder *iface, IStream *stream, str
|
||||||
WICBitmapDecoderCapabilityCanEnumerateMetadata;
|
WICBitmapDecoderCapabilityCanEnumerateMetadata;
|
||||||
st->frame_count = 1;
|
st->frame_count = 1;
|
||||||
|
|
||||||
|
This->stream = stream;
|
||||||
|
|
||||||
hr = S_OK;
|
hr = S_OK;
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
@ -455,6 +458,79 @@ HRESULT CDECL png_decoder_copy_pixels(struct decoder *iface, UINT frame,
|
||||||
prc, stride, buffersize, buffer);
|
prc, stride, buffersize, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT CDECL png_decoder_get_metadata_blocks(struct decoder* iface,
|
||||||
|
UINT frame, UINT *count, struct decoder_block **blocks)
|
||||||
|
{
|
||||||
|
struct png_decoder *This = impl_from_decoder(iface);
|
||||||
|
HRESULT hr;
|
||||||
|
struct decoder_block *result = NULL;
|
||||||
|
ULONGLONG seek;
|
||||||
|
BYTE chunk_type[4];
|
||||||
|
ULONG chunk_size;
|
||||||
|
ULONGLONG chunk_start;
|
||||||
|
ULONG metadata_blocks_size = 0;
|
||||||
|
|
||||||
|
seek = 8;
|
||||||
|
*count = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
hr = stream_seek(This->stream, seek, STREAM_SEEK_SET, &chunk_start);
|
||||||
|
if (FAILED(hr)) goto end;
|
||||||
|
|
||||||
|
hr = read_png_chunk(This->stream, chunk_type, NULL, &chunk_size);
|
||||||
|
if (FAILED(hr)) goto end;
|
||||||
|
|
||||||
|
if (chunk_type[0] >= 'a' && chunk_type[0] <= 'z' &&
|
||||||
|
memcmp(chunk_type, "tRNS", 4) && memcmp(chunk_type, "pHYs", 4))
|
||||||
|
{
|
||||||
|
/* This chunk is considered metadata. */
|
||||||
|
if (*count == metadata_blocks_size)
|
||||||
|
{
|
||||||
|
struct decoder_block *new_metadata_blocks;
|
||||||
|
ULONG new_metadata_blocks_size;
|
||||||
|
|
||||||
|
new_metadata_blocks_size = 4 + metadata_blocks_size * 2;
|
||||||
|
new_metadata_blocks = RtlAllocateHeap(GetProcessHeap(), 0,
|
||||||
|
new_metadata_blocks_size * sizeof(*new_metadata_blocks));
|
||||||
|
|
||||||
|
if (!new_metadata_blocks)
|
||||||
|
{
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(new_metadata_blocks, result,
|
||||||
|
*count * sizeof(*new_metadata_blocks));
|
||||||
|
|
||||||
|
RtlFreeHeap(GetProcessHeap(), 0, result);
|
||||||
|
result = new_metadata_blocks;
|
||||||
|
metadata_blocks_size = new_metadata_blocks_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
result[*count].offset = chunk_start;
|
||||||
|
result[*count].length = chunk_size + 12;
|
||||||
|
result[*count].options = WICMetadataCreationAllowUnknown;
|
||||||
|
(*count)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
seek = chunk_start + chunk_size + 12; /* skip data and CRC */
|
||||||
|
} while (memcmp(chunk_type, "IEND", 4));
|
||||||
|
|
||||||
|
end:
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
*blocks = result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*count = 0;
|
||||||
|
*blocks = NULL;
|
||||||
|
RtlFreeHeap(GetProcessHeap(), 0, result);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
@ -467,6 +543,7 @@ static const struct decoder_funcs png_decoder_vtable = {
|
||||||
png_decoder_initialize,
|
png_decoder_initialize,
|
||||||
png_decoder_get_frame_info,
|
png_decoder_get_frame_info,
|
||||||
png_decoder_copy_pixels,
|
png_decoder_copy_pixels,
|
||||||
|
png_decoder_get_metadata_blocks,
|
||||||
png_decoder_destroy
|
png_decoder_destroy
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
|
#include "winternl.h"
|
||||||
#include "objbase.h"
|
#include "objbase.h"
|
||||||
|
|
||||||
#include "wincodecs_private.h"
|
#include "wincodecs_private.h"
|
||||||
|
|
|
@ -44,47 +44,6 @@ static inline ULONG read_ulong_be(BYTE* data)
|
||||||
return data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
|
return data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT read_png_chunk(IStream *stream, BYTE *type, BYTE **data, ULONG *data_size)
|
|
||||||
{
|
|
||||||
BYTE header[8];
|
|
||||||
HRESULT hr;
|
|
||||||
ULONG bytesread;
|
|
||||||
|
|
||||||
hr = IStream_Read(stream, header, 8, &bytesread);
|
|
||||||
if (FAILED(hr) || bytesread < 8)
|
|
||||||
{
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
hr = E_FAIL;
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
*data_size = read_ulong_be(&header[0]);
|
|
||||||
|
|
||||||
memcpy(type, &header[4], 4);
|
|
||||||
|
|
||||||
if (data)
|
|
||||||
{
|
|
||||||
*data = HeapAlloc(GetProcessHeap(), 0, *data_size);
|
|
||||||
if (!*data)
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
|
|
||||||
hr = IStream_Read(stream, *data, *data_size, &bytesread);
|
|
||||||
|
|
||||||
if (FAILED(hr) || bytesread < *data_size)
|
|
||||||
{
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
hr = E_FAIL;
|
|
||||||
HeapFree(GetProcessHeap(), 0, *data);
|
|
||||||
*data = NULL;
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Windows ignores CRC of the chunk */
|
|
||||||
}
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT LoadTextMetadata(IStream *stream, const GUID *preferred_vendor,
|
static HRESULT LoadTextMetadata(IStream *stream, const GUID *preferred_vendor,
|
||||||
DWORD persist_options, MetadataItem **items, DWORD *item_count)
|
DWORD persist_options, MetadataItem **items, DWORD *item_count)
|
||||||
{
|
{
|
||||||
|
@ -459,7 +418,7 @@ typedef struct {
|
||||||
BYTE *image_bits;
|
BYTE *image_bits;
|
||||||
CRITICAL_SECTION lock; /* must be held when png structures are accessed or initialized is set */
|
CRITICAL_SECTION lock; /* must be held when png structures are accessed or initialized is set */
|
||||||
ULONG metadata_count;
|
ULONG metadata_count;
|
||||||
metadata_block_info* metadata_blocks;
|
struct decoder_block* metadata_blocks;
|
||||||
} PngDecoder;
|
} PngDecoder;
|
||||||
|
|
||||||
static inline PngDecoder *impl_from_IWICBitmapDecoder(IWICBitmapDecoder *iface)
|
static inline PngDecoder *impl_from_IWICBitmapDecoder(IWICBitmapDecoder *iface)
|
||||||
|
@ -515,7 +474,6 @@ static ULONG WINAPI PngDecoder_Release(IWICBitmapDecoder *iface)
|
||||||
{
|
{
|
||||||
PngDecoder *This = impl_from_IWICBitmapDecoder(iface);
|
PngDecoder *This = impl_from_IWICBitmapDecoder(iface);
|
||||||
ULONG ref = InterlockedDecrement(&This->ref);
|
ULONG ref = InterlockedDecrement(&This->ref);
|
||||||
ULONG i;
|
|
||||||
|
|
||||||
TRACE("(%p) refcount=%u\n", iface, ref);
|
TRACE("(%p) refcount=%u\n", iface, ref);
|
||||||
|
|
||||||
|
@ -530,11 +488,6 @@ static ULONG WINAPI PngDecoder_Release(IWICBitmapDecoder *iface)
|
||||||
This->lock.DebugInfo->Spare[0] = 0;
|
This->lock.DebugInfo->Spare[0] = 0;
|
||||||
DeleteCriticalSection(&This->lock);
|
DeleteCriticalSection(&This->lock);
|
||||||
HeapFree(GetProcessHeap(), 0, This->image_bits);
|
HeapFree(GetProcessHeap(), 0, This->image_bits);
|
||||||
for (i=0; i<This->metadata_count; i++)
|
|
||||||
{
|
|
||||||
if (This->metadata_blocks[i].reader)
|
|
||||||
IWICMetadataReader_Release(This->metadata_blocks[i].reader);
|
|
||||||
}
|
|
||||||
HeapFree(GetProcessHeap(), 0, This->metadata_blocks);
|
HeapFree(GetProcessHeap(), 0, This->metadata_blocks);
|
||||||
HeapFree(GetProcessHeap(), 0, This);
|
HeapFree(GetProcessHeap(), 0, This);
|
||||||
}
|
}
|
||||||
|
@ -587,10 +540,6 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
|
||||||
png_uint_32 transparency;
|
png_uint_32 transparency;
|
||||||
png_color_16p trans_values;
|
png_color_16p trans_values;
|
||||||
jmp_buf jmpbuf;
|
jmp_buf jmpbuf;
|
||||||
BYTE chunk_type[4];
|
|
||||||
ULONG chunk_size;
|
|
||||||
ULARGE_INTEGER chunk_start;
|
|
||||||
ULONG metadata_blocks_size = 0;
|
|
||||||
|
|
||||||
TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions);
|
TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions);
|
||||||
|
|
||||||
|
@ -783,52 +732,7 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
|
||||||
|
|
||||||
ppng_read_end(This->png_ptr, This->end_info);
|
ppng_read_end(This->png_ptr, This->end_info);
|
||||||
|
|
||||||
/* Find the metadata chunks in the file. */
|
decoder_get_metadata_blocks(This->png_decoder, 0, &This->metadata_count, &This->metadata_blocks);
|
||||||
seek.QuadPart = 8;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
hr = IStream_Seek(pIStream, seek, STREAM_SEEK_SET, &chunk_start);
|
|
||||||
if (FAILED(hr)) goto end;
|
|
||||||
|
|
||||||
hr = read_png_chunk(pIStream, chunk_type, NULL, &chunk_size);
|
|
||||||
if (FAILED(hr)) goto end;
|
|
||||||
|
|
||||||
if (chunk_type[0] >= 'a' && chunk_type[0] <= 'z' &&
|
|
||||||
memcmp(chunk_type, "tRNS", 4) && memcmp(chunk_type, "pHYs", 4))
|
|
||||||
{
|
|
||||||
/* This chunk is considered metadata. */
|
|
||||||
if (This->metadata_count == metadata_blocks_size)
|
|
||||||
{
|
|
||||||
metadata_block_info* new_metadata_blocks;
|
|
||||||
ULONG new_metadata_blocks_size;
|
|
||||||
|
|
||||||
new_metadata_blocks_size = 4 + metadata_blocks_size * 2;
|
|
||||||
new_metadata_blocks = HeapAlloc(GetProcessHeap(), 0,
|
|
||||||
new_metadata_blocks_size * sizeof(*new_metadata_blocks));
|
|
||||||
|
|
||||||
if (!new_metadata_blocks)
|
|
||||||
{
|
|
||||||
hr = E_OUTOFMEMORY;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(new_metadata_blocks, This->metadata_blocks,
|
|
||||||
This->metadata_count * sizeof(*new_metadata_blocks));
|
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(), 0, This->metadata_blocks);
|
|
||||||
This->metadata_blocks = new_metadata_blocks;
|
|
||||||
metadata_blocks_size = new_metadata_blocks_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
This->metadata_blocks[This->metadata_count].ofs = chunk_start;
|
|
||||||
This->metadata_blocks[This->metadata_count].len.QuadPart = chunk_size + 12;
|
|
||||||
This->metadata_blocks[This->metadata_count].reader = NULL;
|
|
||||||
This->metadata_count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
seek.QuadPart = chunk_start.QuadPart + chunk_size + 12; /* skip data and CRC */
|
|
||||||
} while (memcmp(chunk_type, "IEND", 4));
|
|
||||||
|
|
||||||
This->stream = pIStream;
|
This->stream = pIStream;
|
||||||
IStream_AddRef(This->stream);
|
IStream_AddRef(This->stream);
|
||||||
|
@ -1185,39 +1089,34 @@ static HRESULT WINAPI PngDecoder_Block_GetReaderByIndex(IWICMetadataBlockReader
|
||||||
if (nIndex >= This->metadata_count || !ppIMetadataReader)
|
if (nIndex >= This->metadata_count || !ppIMetadataReader)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
|
||||||
if (!This->metadata_blocks[nIndex].reader)
|
hr = StreamImpl_Create(&stream);
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
hr = StreamImpl_Create(&stream);
|
ULARGE_INTEGER offset, length;
|
||||||
|
|
||||||
|
offset.QuadPart = This->metadata_blocks[nIndex].offset;
|
||||||
|
length.QuadPart = This->metadata_blocks[nIndex].length;
|
||||||
|
hr = IWICStream_InitializeFromIStreamRegion(stream, This->stream,
|
||||||
|
offset, length);
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
hr = ImagingFactory_CreateInstance(&IID_IWICComponentFactory, (void**)&factory);
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
hr = IWICStream_InitializeFromIStreamRegion(stream, This->stream,
|
hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory,
|
||||||
This->metadata_blocks[nIndex].ofs, This->metadata_blocks[nIndex].len);
|
&GUID_ContainerFormatPng, NULL, This->metadata_blocks[nIndex].options,
|
||||||
|
(IStream*)stream, ppIMetadataReader);
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
IWICComponentFactory_Release(factory);
|
||||||
hr = ImagingFactory_CreateInstance(&IID_IWICComponentFactory, (void**)&factory);
|
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
{
|
|
||||||
hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory,
|
|
||||||
&GUID_ContainerFormatPng, NULL, WICMetadataCreationAllowUnknown,
|
|
||||||
(IStream*)stream, &This->metadata_blocks[nIndex].reader);
|
|
||||||
|
|
||||||
IWICComponentFactory_Release(factory);
|
|
||||||
}
|
|
||||||
|
|
||||||
IWICStream_Release(stream);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FAILED(hr))
|
IWICStream_Release(stream);
|
||||||
{
|
|
||||||
*ppIMetadataReader = NULL;
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*ppIMetadataReader = This->metadata_blocks[nIndex].reader;
|
if (FAILED(hr))
|
||||||
IWICMetadataReader_AddRef(*ppIMetadataReader);
|
*ppIMetadataReader = NULL;
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,6 +85,13 @@ HRESULT CDECL decoder_wrapper_copy_pixels(struct decoder* iface, UINT frame,
|
||||||
return unix_funcs->decoder_copy_pixels(This->unix_decoder, frame, prc, stride, buffersize, buffer);
|
return unix_funcs->decoder_copy_pixels(This->unix_decoder, frame, prc, stride, buffersize, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT CDECL decoder_wrapper_get_metadata_blocks(struct decoder* iface,
|
||||||
|
UINT frame, UINT *count, struct decoder_block **blocks)
|
||||||
|
{
|
||||||
|
struct decoder_wrapper* This = impl_from_decoder(iface);
|
||||||
|
return unix_funcs->decoder_get_metadata_blocks(This->unix_decoder, frame, count, blocks);
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
@ -96,6 +103,7 @@ static const struct decoder_funcs decoder_wrapper_vtable = {
|
||||||
decoder_wrapper_initialize,
|
decoder_wrapper_initialize,
|
||||||
decoder_wrapper_get_frame_info,
|
decoder_wrapper_get_frame_info,
|
||||||
decoder_wrapper_copy_pixels,
|
decoder_wrapper_copy_pixels,
|
||||||
|
decoder_wrapper_get_metadata_blocks,
|
||||||
decoder_wrapper_destroy
|
decoder_wrapper_destroy
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,7 @@ static const struct unix_funcs unix_funcs = {
|
||||||
decoder_initialize,
|
decoder_initialize,
|
||||||
decoder_get_frame_info,
|
decoder_get_frame_info,
|
||||||
decoder_copy_pixels,
|
decoder_copy_pixels,
|
||||||
|
decoder_get_metadata_blocks,
|
||||||
decoder_destroy
|
decoder_destroy
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,11 @@ HRESULT CDECL decoder_copy_pixels(struct decoder *decoder, UINT frame,
|
||||||
return decoder->vtable->copy_pixels(decoder, frame, prc, stride, buffersize, buffer);
|
return decoder->vtable->copy_pixels(decoder, frame, prc, stride, buffersize, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT CDECL decoder_get_metadata_blocks(struct decoder *decoder, UINT frame, UINT *count, struct decoder_block **blocks)
|
||||||
|
{
|
||||||
|
return decoder->vtable->get_metadata_blocks(decoder, frame, count, blocks);
|
||||||
|
}
|
||||||
|
|
||||||
void CDECL decoder_destroy(struct decoder *decoder)
|
void CDECL decoder_destroy(struct decoder *decoder)
|
||||||
{
|
{
|
||||||
decoder->vtable->destroy(decoder);
|
decoder->vtable->destroy(decoder);
|
||||||
|
@ -101,3 +106,49 @@ HRESULT copy_pixels(UINT bpp, const BYTE *srcbuffer,
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline ULONG read_ulong_be(BYTE* data)
|
||||||
|
{
|
||||||
|
return data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT read_png_chunk(IStream *stream, BYTE *type, BYTE **data, ULONG *data_size)
|
||||||
|
{
|
||||||
|
BYTE header[8];
|
||||||
|
HRESULT hr;
|
||||||
|
ULONG bytesread;
|
||||||
|
|
||||||
|
hr = stream_read(stream, header, 8, &bytesread);
|
||||||
|
if (FAILED(hr) || bytesread < 8)
|
||||||
|
{
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
hr = E_FAIL;
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
*data_size = read_ulong_be(&header[0]);
|
||||||
|
|
||||||
|
memcpy(type, &header[4], 4);
|
||||||
|
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
*data = RtlAllocateHeap(GetProcessHeap(), 0, *data_size);
|
||||||
|
if (!*data)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
hr = stream_read(stream, *data, *data_size, &bytesread);
|
||||||
|
|
||||||
|
if (FAILED(hr) || bytesread < *data_size)
|
||||||
|
{
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
hr = E_FAIL;
|
||||||
|
RtlFreeHeap(GetProcessHeap(), 0, *data);
|
||||||
|
*data = NULL;
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Windows ignores CRC of the chunk */
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
|
@ -249,6 +249,8 @@ static inline const char *debug_wic_rect(const WICRect *rect)
|
||||||
|
|
||||||
extern HMODULE windowscodecs_module;
|
extern HMODULE windowscodecs_module;
|
||||||
|
|
||||||
|
HRESULT read_png_chunk(IStream *stream, BYTE *type, BYTE **data, ULONG *data_size);
|
||||||
|
|
||||||
/* unixlib iface */
|
/* unixlib iface */
|
||||||
struct decoder_funcs;
|
struct decoder_funcs;
|
||||||
|
|
||||||
|
@ -277,6 +279,13 @@ struct decoder_frame
|
||||||
WICColor palette[256];
|
WICColor palette[256];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct decoder_block
|
||||||
|
{
|
||||||
|
ULONGLONG offset;
|
||||||
|
ULONGLONG length;
|
||||||
|
DWORD options;
|
||||||
|
};
|
||||||
|
|
||||||
struct decoder
|
struct decoder
|
||||||
{
|
{
|
||||||
const struct decoder_funcs *vtable;
|
const struct decoder_funcs *vtable;
|
||||||
|
@ -288,6 +297,8 @@ struct decoder_funcs
|
||||||
HRESULT (CDECL *get_frame_info)(struct decoder* This, UINT frame, struct decoder_frame *info);
|
HRESULT (CDECL *get_frame_info)(struct decoder* This, UINT frame, struct decoder_frame *info);
|
||||||
HRESULT (CDECL *copy_pixels)(struct decoder* This, UINT frame, const WICRect *prc,
|
HRESULT (CDECL *copy_pixels)(struct decoder* This, UINT frame, const WICRect *prc,
|
||||||
UINT stride, UINT buffersize, BYTE *buffer);
|
UINT stride, UINT buffersize, BYTE *buffer);
|
||||||
|
HRESULT (CDECL *get_metadata_blocks)(struct decoder* This, UINT frame, UINT *count,
|
||||||
|
struct decoder_block **blocks);
|
||||||
void (CDECL *destroy)(struct decoder* This);
|
void (CDECL *destroy)(struct decoder* This);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -305,6 +316,8 @@ HRESULT CDECL decoder_initialize(struct decoder *This, IStream *stream, struct d
|
||||||
HRESULT CDECL decoder_get_frame_info(struct decoder* This, UINT frame, struct decoder_frame *info);
|
HRESULT CDECL decoder_get_frame_info(struct decoder* This, UINT frame, struct decoder_frame *info);
|
||||||
HRESULT CDECL decoder_copy_pixels(struct decoder* This, UINT frame, const WICRect *prc,
|
HRESULT CDECL decoder_copy_pixels(struct decoder* This, UINT frame, const WICRect *prc,
|
||||||
UINT stride, UINT buffersize, BYTE *buffer);
|
UINT stride, UINT buffersize, BYTE *buffer);
|
||||||
|
HRESULT CDECL decoder_get_metadata_blocks(struct decoder* This, UINT frame, UINT *count,
|
||||||
|
struct decoder_block **blocks);
|
||||||
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);
|
||||||
|
@ -316,6 +329,8 @@ struct unix_funcs
|
||||||
HRESULT (CDECL *decoder_get_frame_info)(struct decoder* This, UINT frame, struct decoder_frame *info);
|
HRESULT (CDECL *decoder_get_frame_info)(struct decoder* This, UINT frame, struct decoder_frame *info);
|
||||||
HRESULT (CDECL *decoder_copy_pixels)(struct decoder* This, UINT frame, const WICRect *prc,
|
HRESULT (CDECL *decoder_copy_pixels)(struct decoder* This, UINT frame, const WICRect *prc,
|
||||||
UINT stride, UINT buffersize, BYTE *buffer);
|
UINT stride, UINT buffersize, BYTE *buffer);
|
||||||
|
HRESULT (CDECL *decoder_get_metadata_blocks)(struct decoder* This, UINT frame, UINT *count,
|
||||||
|
struct decoder_block **blocks);
|
||||||
void (CDECL *decoder_destroy)(struct decoder* This);
|
void (CDECL *decoder_destroy)(struct decoder* This);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue