Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
6aa8e179
Commit
6aa8e179
authored
Oct 09, 2020
by
Esme Povirk
Committed by
Alexandre Julliard
Oct 19, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
windowscodecs: Start loading PNG in unix lib.
Signed-off-by:
Esme Povirk
<
esme@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
0f61ed18
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
247 additions
and
6 deletions
+247
-6
libpng.c
dlls/windowscodecs/libpng.c
+158
-1
main.c
dlls/windowscodecs/main.c
+19
-0
pngformat.c
dlls/windowscodecs/pngformat.c
+17
-4
unix_iface.c
dlls/windowscodecs/unix_iface.c
+13
-1
unix_lib.c
dlls/windowscodecs/unix_lib.c
+15
-0
wincodecs_common.h
dlls/windowscodecs/wincodecs_common.h
+5
-0
wincodecs_private.h
dlls/windowscodecs/wincodecs_private.h
+20
-0
No files found.
dlls/windowscodecs/libpng.c
View file @
6aa8e179
...
...
@@ -42,6 +42,67 @@ WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
#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
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
);
}
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
)
{
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
=
{
png_decoder_initialize
,
png_decoder_destroy
};
...
...
@@ -67,7 +220,11 @@ HRESULT CDECL png_decoder_create(struct decoder_info *info, struct decoder **res
{
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
));
...
...
dlls/windowscodecs/main.c
View file @
6aa8e179
...
...
@@ -255,6 +255,25 @@ HRESULT write_source(IWICBitmapFrameEncode *iface,
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
)
{
UINT
x
,
y
;
...
...
dlls/windowscodecs/pngformat.c
View file @
6aa8e179
...
...
@@ -446,6 +446,7 @@ typedef struct {
IStream
*
stream
;
struct
decoder
*
png_decoder
;
struct
decoder_info
decoder_info
;
struct
decoder_stat
file_info
;
png_structp
png_ptr
;
png_infop
info_ptr
;
png_infop
end_info
;
...
...
@@ -543,6 +544,7 @@ static ULONG WINAPI PngDecoder_Release(IWICBitmapDecoder *iface)
static
HRESULT
WINAPI
PngDecoder_QueryCapability
(
IWICBitmapDecoder
*
iface
,
IStream
*
stream
,
DWORD
*
capability
)
{
PngDecoder
*
This
=
impl_from_IWICBitmapDecoder
(
iface
);
HRESULT
hr
;
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
);
if
(
hr
!=
S_OK
)
return
hr
;
*
capability
=
WICBitmapDecoderCapabilityCanDecodeAllImages
|
WICBitmapDecoderCapabilityCanDecodeSomeImages
;
/* FIXME: WICBitmapDecoderCapabilityCanEnumerateMetadata */
*
capability
=
(
This
->
file_info
.
flags
&
DECODER_FLAGS_CAPABILITY_MASK
);
return
S_OK
;
}
...
...
@@ -595,6 +595,16 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
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 */
This
->
png_ptr
=
ppng_create_read_struct
(
PNG_LIBPNG_VER_STRING
,
NULL
,
NULL
,
NULL
);
if
(
!
This
->
png_ptr
)
...
...
@@ -896,9 +906,12 @@ static HRESULT WINAPI PngDecoder_GetThumbnail(IWICBitmapDecoder *iface,
static
HRESULT
WINAPI
PngDecoder_GetFrameCount
(
IWICBitmapDecoder
*
iface
,
UINT
*
pCount
)
{
PngDecoder
*
This
=
impl_from_IWICBitmapDecoder
(
iface
);
if
(
!
pCount
)
return
E_INVALIDARG
;
*
pCount
=
1
;
if
(
!
This
->
initialized
)
return
WINCODEC_ERR_WRONGSTATE
;
*
pCount
=
This
->
file_info
.
frame_count
;
return
S_OK
;
}
...
...
dlls/windowscodecs/unix_iface.c
View file @
6aa8e179
...
...
@@ -39,9 +39,14 @@ static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT;
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
)
{
__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
;
}
...
...
@@ -61,6 +66,12 @@ static inline struct decoder_wrapper *impl_from_decoder(struct decoder* iface)
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
)
{
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
=
{
decoder_wrapper_initialize
,
decoder_wrapper_destroy
};
...
...
dlls/windowscodecs/unix_lib.c
View file @
6aa8e179
...
...
@@ -43,6 +43,18 @@
#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
)
{
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
=
{
decoder_create
,
decoder_initialize
,
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
;
win32_funcs
=
ptr_in
;
*
(
const
struct
unix_funcs
**
)
ptr_out
=
&
unix_funcs
;
return
STATUS_SUCCESS
;
}
dlls/windowscodecs/wincodecs_common.h
View file @
6aa8e179
...
...
@@ -16,6 +16,11 @@
* 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
)
{
decoder
->
vtable
->
destroy
(
decoder
);
...
...
dlls/windowscodecs/wincodecs_private.h
View file @
6aa8e179
...
...
@@ -259,6 +259,14 @@ struct decoder_info
CLSID
clsid
;
};
#define DECODER_FLAGS_CAPABILITY_MASK 0x1f
struct
decoder_stat
{
DWORD
flags
;
DWORD
frame_count
;
};
struct
decoder
{
const
struct
decoder_funcs
*
vtable
;
...
...
@@ -266,10 +274,21 @@ struct decoder
struct
decoder_funcs
{
HRESULT
(
CDECL
*
initialize
)(
struct
decoder
*
This
,
IStream
*
stream
,
struct
decoder_stat
*
st
);
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_initialize
(
struct
decoder
*
This
,
IStream
*
stream
,
struct
decoder_stat
*
st
);
void
CDECL
decoder_destroy
(
struct
decoder
*
This
);
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
{
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
);
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment