mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-26 05:38:22 +01:00
cwebp (windows): fix alpha image import on XP
Query the converter to ensure the format is supported; add BGR formats as RGBA was failing for PNG on XP Fixes issue 129 Change-Id: I02e0d74b3b21337bc5fffd6a5dc158b7809b9aa9
This commit is contained in:
parent
1765cb1ca5
commit
eda8ee4b3b
@ -113,6 +113,12 @@ static int ReadYUV(FILE* in_file, WebPPicture* const pic) {
|
|||||||
#define MAKE_REFGUID(x) &(x)
|
#define MAKE_REFGUID(x) &(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef struct WICFormatImporter {
|
||||||
|
const GUID* pixel_format;
|
||||||
|
int bytes_per_pixel;
|
||||||
|
int (*import)(WebPPicture* const, const uint8_t* const, int);
|
||||||
|
} WICFormatImporter;
|
||||||
|
|
||||||
static HRESULT OpenInputStream(const char* filename, IStream** ppStream) {
|
static HRESULT OpenInputStream(const char* filename, IStream** ppStream) {
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
IFS(SHCreateStreamOnFileA(filename, STGM_READ, ppStream));
|
IFS(SHCreateStreamOnFileA(filename, STGM_READ, ppStream));
|
||||||
@ -123,6 +129,31 @@ static HRESULT OpenInputStream(const char* filename, IStream** ppStream) {
|
|||||||
|
|
||||||
static HRESULT ReadPictureWithWIC(const char* filename,
|
static HRESULT ReadPictureWithWIC(const char* filename,
|
||||||
WebPPicture* const pic, int keep_alpha) {
|
WebPPicture* const pic, int keep_alpha) {
|
||||||
|
// From Microsoft SDK 7.0a -- wincodec.h
|
||||||
|
// Create local copies for compatibility when building against earlier
|
||||||
|
// versions of the SDK.
|
||||||
|
WEBP_DEFINE_GUID(GUID_WICPixelFormat24bppBGR_,
|
||||||
|
0x6fddc324, 0x4e03, 0x4bfe,
|
||||||
|
0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0c);
|
||||||
|
WEBP_DEFINE_GUID(GUID_WICPixelFormat24bppRGB_,
|
||||||
|
0x6fddc324, 0x4e03, 0x4bfe,
|
||||||
|
0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0d);
|
||||||
|
WEBP_DEFINE_GUID(GUID_WICPixelFormat32bppBGRA_,
|
||||||
|
0x6fddc324, 0x4e03, 0x4bfe,
|
||||||
|
0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0f);
|
||||||
|
WEBP_DEFINE_GUID(GUID_WICPixelFormat32bppRGBA_,
|
||||||
|
0xf5c7ad2d, 0x6a8d, 0x43dd,
|
||||||
|
0xa7, 0xa8, 0xa2, 0x99, 0x35, 0x26, 0x1a, 0xe9);
|
||||||
|
const WICFormatImporter alphaFormatImporters[] = {
|
||||||
|
{ &GUID_WICPixelFormat32bppBGRA_, 4, WebPPictureImportBGRA },
|
||||||
|
{ &GUID_WICPixelFormat32bppRGBA_, 4, WebPPictureImportRGBA },
|
||||||
|
{ NULL, 0, NULL },
|
||||||
|
};
|
||||||
|
const WICFormatImporter nonAlphaFormatImporters[] = {
|
||||||
|
{ &GUID_WICPixelFormat24bppBGR_, 3, WebPPictureImportBGR },
|
||||||
|
{ &GUID_WICPixelFormat24bppRGB_, 3, WebPPictureImportRGB },
|
||||||
|
{ NULL, 0, NULL },
|
||||||
|
};
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
IWICBitmapFrameDecode* pFrame = NULL;
|
IWICBitmapFrameDecode* pFrame = NULL;
|
||||||
IWICFormatConverter* pConverter = NULL;
|
IWICFormatConverter* pConverter = NULL;
|
||||||
@ -133,6 +164,7 @@ static HRESULT ReadPictureWithWIC(const char* filename,
|
|||||||
UINT width = 0, height = 0;
|
UINT width = 0, height = 0;
|
||||||
BYTE* rgb = NULL;
|
BYTE* rgb = NULL;
|
||||||
WICPixelFormatGUID srcPixelFormat = { 0 };
|
WICPixelFormatGUID srcPixelFormat = { 0 };
|
||||||
|
const WICFormatImporter* importer = NULL;
|
||||||
GUID srcContainerFormat = { 0 };
|
GUID srcContainerFormat = { 0 };
|
||||||
const GUID* alphaContainers[] = {
|
const GUID* alphaContainers[] = {
|
||||||
&GUID_ContainerFormatBmp,
|
&GUID_ContainerFormatBmp,
|
||||||
@ -141,18 +173,6 @@ static HRESULT ReadPictureWithWIC(const char* filename,
|
|||||||
};
|
};
|
||||||
int has_alpha = 0;
|
int has_alpha = 0;
|
||||||
int i, stride;
|
int i, stride;
|
||||||
// From Microsoft SDK 7.0a
|
|
||||||
// Create local copies for compatibility when building against earlier
|
|
||||||
// versions of the SDK.
|
|
||||||
WEBP_DEFINE_GUID(GUID_WICPixelFormat24bppRGB_,
|
|
||||||
0x6fddc324, 0x4e03, 0x4bfe,
|
|
||||||
0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0d);
|
|
||||||
WEBP_DEFINE_GUID(GUID_WICPixelFormat32bppRGBA_,
|
|
||||||
0xf5c7ad2d, 0x6a8d, 0x43dd,
|
|
||||||
0xa7, 0xa8, 0xa2, 0x99, 0x35, 0x26, 0x1a, 0xe9);
|
|
||||||
WEBP_DEFINE_GUID(GUID_WICPixelFormat32bppBGRA_,
|
|
||||||
0x6fddc324, 0x4e03, 0x4bfe,
|
|
||||||
0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0f);
|
|
||||||
|
|
||||||
IFS(CoInitialize(NULL));
|
IFS(CoInitialize(NULL));
|
||||||
IFS(CoCreateInstance(MAKE_REFGUID(CLSID_WICImagingFactory), NULL,
|
IFS(CoCreateInstance(MAKE_REFGUID(CLSID_WICImagingFactory), NULL,
|
||||||
@ -195,15 +215,27 @@ static HRESULT ReadPictureWithWIC(const char* filename,
|
|||||||
|
|
||||||
// Prepare for pixel format conversion (if necessary).
|
// Prepare for pixel format conversion (if necessary).
|
||||||
IFS(IWICImagingFactory_CreateFormatConverter(pFactory, &pConverter));
|
IFS(IWICImagingFactory_CreateFormatConverter(pFactory, &pConverter));
|
||||||
|
|
||||||
|
for (importer = has_alpha ? alphaFormatImporters : nonAlphaFormatImporters;
|
||||||
|
hr == S_OK && importer->import != NULL; ++importer) {
|
||||||
|
BOOL canConvert;
|
||||||
|
const HRESULT cchr = IWICFormatConverter_CanConvert(
|
||||||
|
pConverter,
|
||||||
|
MAKE_REFGUID(srcPixelFormat),
|
||||||
|
MAKE_REFGUID(*importer->pixel_format),
|
||||||
|
&canConvert);
|
||||||
|
if (SUCCEEDED(cchr) && canConvert) break;
|
||||||
|
}
|
||||||
|
if (importer->import == NULL) hr = E_FAIL;
|
||||||
|
|
||||||
IFS(IWICFormatConverter_Initialize(pConverter, (IWICBitmapSource*)pFrame,
|
IFS(IWICFormatConverter_Initialize(pConverter, (IWICBitmapSource*)pFrame,
|
||||||
has_alpha ? MAKE_REFGUID(GUID_WICPixelFormat32bppRGBA_)
|
importer->pixel_format,
|
||||||
: MAKE_REFGUID(GUID_WICPixelFormat24bppRGB_),
|
|
||||||
WICBitmapDitherTypeNone,
|
WICBitmapDitherTypeNone,
|
||||||
NULL, 0.0, WICBitmapPaletteTypeCustom));
|
NULL, 0.0, WICBitmapPaletteTypeCustom));
|
||||||
|
|
||||||
// Decode.
|
// Decode.
|
||||||
IFS(IWICFormatConverter_GetSize(pConverter, &width, &height));
|
IFS(IWICFormatConverter_GetSize(pConverter, &width, &height));
|
||||||
stride = (has_alpha ? 4 : 3) * width * sizeof(*rgb);
|
stride = importer->bytes_per_pixel * width * sizeof(*rgb);
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
rgb = (BYTE*)malloc(stride * height);
|
rgb = (BYTE*)malloc(stride * height);
|
||||||
if (rgb == NULL)
|
if (rgb == NULL)
|
||||||
@ -217,8 +249,7 @@ static HRESULT ReadPictureWithWIC(const char* filename,
|
|||||||
int ok;
|
int ok;
|
||||||
pic->width = width;
|
pic->width = width;
|
||||||
pic->height = height;
|
pic->height = height;
|
||||||
ok = has_alpha ? WebPPictureImportRGBA(pic, rgb, stride)
|
ok = importer->import(pic, rgb, stride);
|
||||||
: WebPPictureImportRGB(pic, rgb, stride);
|
|
||||||
if (!ok)
|
if (!ok)
|
||||||
hr = E_FAIL;
|
hr = E_FAIL;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user