mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-26 13:48:21 +01:00
Merge "examples: (windows/WIC) add alpha support"
This commit is contained in:
commit
3827e1bce4
@ -44,6 +44,10 @@
|
|||||||
DEFINE_GUID(GUID_WICPixelFormat24bppRGB,
|
DEFINE_GUID(GUID_WICPixelFormat24bppRGB,
|
||||||
0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0d);
|
0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0d);
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef GUID_WICPixelFormat32bppRGBA
|
||||||
|
DEFINE_GUID(GUID_WICPixelFormat32bppRGBA,
|
||||||
|
0xf5c7ad2d, 0x6a8d, 0x43dd, 0xa7, 0xa8, 0xa2, 0x99, 0x35, 0x26, 0x1a, 0xe9);
|
||||||
|
#endif
|
||||||
#endif /* HAVE_WINCODEC_H */
|
#endif /* HAVE_WINCODEC_H */
|
||||||
|
|
||||||
|
|
||||||
@ -109,7 +113,7 @@ static HRESULT OpenInputStream(const char* filename, IStream** ppStream) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT ReadPictureWithWIC(const char* filename,
|
static HRESULT ReadPictureWithWIC(const char* filename,
|
||||||
WebPPicture* const pic) {
|
WebPPicture* const pic, int keep_alpha) {
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
IWICBitmapFrameDecode* pFrame = NULL;
|
IWICBitmapFrameDecode* pFrame = NULL;
|
||||||
IWICFormatConverter* pConverter = NULL;
|
IWICFormatConverter* pConverter = NULL;
|
||||||
@ -119,6 +123,15 @@ static HRESULT ReadPictureWithWIC(const char* filename,
|
|||||||
UINT frameCount = 0;
|
UINT frameCount = 0;
|
||||||
UINT width, height = 0;
|
UINT width, height = 0;
|
||||||
BYTE* rgb = NULL;
|
BYTE* rgb = NULL;
|
||||||
|
WICPixelFormatGUID srcPixelFormat = { 0 };
|
||||||
|
GUID srcContainerFormat = { 0 };
|
||||||
|
const GUID* alphaContainers[] = {
|
||||||
|
&GUID_ContainerFormatBmp,
|
||||||
|
&GUID_ContainerFormatPng,
|
||||||
|
&GUID_ContainerFormatTiff
|
||||||
|
};
|
||||||
|
int has_alpha = 0;
|
||||||
|
int i, stride;
|
||||||
|
|
||||||
IFS(CoInitialize(NULL));
|
IFS(CoInitialize(NULL));
|
||||||
IFS(CoCreateInstance(MAKE_REFGUID(CLSID_WICImagingFactory), NULL,
|
IFS(CoCreateInstance(MAKE_REFGUID(CLSID_WICImagingFactory), NULL,
|
||||||
@ -139,28 +152,53 @@ static HRESULT ReadPictureWithWIC(const char* filename,
|
|||||||
hr = E_FAIL;
|
hr = E_FAIL;
|
||||||
}
|
}
|
||||||
IFS(IWICBitmapDecoder_GetFrame(pDecoder, 0, &pFrame));
|
IFS(IWICBitmapDecoder_GetFrame(pDecoder, 0, &pFrame));
|
||||||
|
IFS(IWICBitmapFrameDecode_GetPixelFormat(pFrame, &srcPixelFormat));
|
||||||
|
IFS(IWICBitmapDecoder_GetContainerFormat(pDecoder, &srcContainerFormat));
|
||||||
|
|
||||||
|
has_alpha = keep_alpha;
|
||||||
|
for (i = 0;
|
||||||
|
has_alpha && i < sizeof(alphaContainers)/sizeof(alphaContainers[0]);
|
||||||
|
++i) {
|
||||||
|
if (IsEqualGUID(&srcContainerFormat, alphaContainers[i])) {
|
||||||
|
has_alpha =
|
||||||
|
IsEqualGUID(&srcPixelFormat, &GUID_WICPixelFormat32bppRGBA) ||
|
||||||
|
IsEqualGUID(&srcPixelFormat, &GUID_WICPixelFormat32bppBGRA);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Prepare for pixel format conversion (if necessary).
|
// Prepare for pixel format conversion (if necessary).
|
||||||
IFS(IWICImagingFactory_CreateFormatConverter(pFactory, &pConverter));
|
IFS(IWICImagingFactory_CreateFormatConverter(pFactory, &pConverter));
|
||||||
IFS(IWICFormatConverter_Initialize(pConverter, (IWICBitmapSource*)pFrame,
|
IFS(IWICFormatConverter_Initialize(pConverter, (IWICBitmapSource*)pFrame,
|
||||||
MAKE_REFGUID(GUID_WICPixelFormat24bppRGB), WICBitmapDitherTypeNone,
|
has_alpha ? MAKE_REFGUID(GUID_WICPixelFormat32bppRGBA)
|
||||||
|
: MAKE_REFGUID(GUID_WICPixelFormat24bppRGB),
|
||||||
|
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);
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
rgb = (BYTE*)malloc(3 * width * height);
|
rgb = (BYTE*)malloc(stride * height);
|
||||||
if (rgb == NULL)
|
if (rgb == NULL)
|
||||||
hr = E_OUTOFMEMORY;
|
hr = E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
IFS(IWICFormatConverter_CopyPixels(pConverter, NULL, 3 * width,
|
IFS(IWICFormatConverter_CopyPixels(pConverter, NULL, stride,
|
||||||
3 * width * height, rgb));
|
stride * height, rgb));
|
||||||
|
|
||||||
// WebP conversion.
|
// WebP conversion.
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
|
int ok;
|
||||||
|
#ifdef WEBP_EXPERIMENTAL_FEATURES
|
||||||
|
if (has_alpha) {
|
||||||
|
pic->colorspace |= WEBP_CSP_ALPHA_BIT;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
pic->width = width;
|
pic->width = width;
|
||||||
pic->height = height;
|
pic->height = height;
|
||||||
if (!WebPPictureImportRGB(pic, rgb, 3 * width))
|
ok = has_alpha ? WebPPictureImportRGBA(pic, rgb, stride)
|
||||||
|
: WebPPictureImportRGB(pic, rgb, stride);
|
||||||
|
if (!ok)
|
||||||
hr = E_FAIL;
|
hr = E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,7 +226,7 @@ static int ReadPicture(const char* const filename, WebPPicture* const pic,
|
|||||||
fclose(in_file);
|
fclose(in_file);
|
||||||
} else {
|
} else {
|
||||||
// If no size specified, try to decode it using WIC.
|
// If no size specified, try to decode it using WIC.
|
||||||
ok = SUCCEEDED(ReadPictureWithWIC(filename, pic));
|
ok = SUCCEEDED(ReadPictureWithWIC(filename, pic, keep_alpha));
|
||||||
}
|
}
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
fprintf(stderr, "Error! Could not process file %s\n", filename);
|
fprintf(stderr, "Error! Could not process file %s\n", filename);
|
||||||
|
@ -86,13 +86,14 @@ static HRESULT CreateOutputStream(const char* out_file_name,
|
|||||||
|
|
||||||
static HRESULT WriteUsingWIC(const char* out_file_name, REFGUID container_guid,
|
static HRESULT WriteUsingWIC(const char* out_file_name, REFGUID container_guid,
|
||||||
unsigned char* rgb, int stride,
|
unsigned char* rgb, int stride,
|
||||||
uint32_t width, uint32_t height) {
|
uint32_t width, uint32_t height, int has_alpha) {
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
IWICImagingFactory* pFactory = NULL;
|
IWICImagingFactory* pFactory = NULL;
|
||||||
IWICBitmapFrameEncode* pFrame = NULL;
|
IWICBitmapFrameEncode* pFrame = NULL;
|
||||||
IWICBitmapEncoder* pEncoder = NULL;
|
IWICBitmapEncoder* pEncoder = NULL;
|
||||||
IStream* pStream = NULL;
|
IStream* pStream = NULL;
|
||||||
GUID pixel_format = GUID_WICPixelFormat24bppBGR;
|
WICPixelFormatGUID pixel_format = has_alpha ? GUID_WICPixelFormat32bppBGRA
|
||||||
|
: GUID_WICPixelFormat24bppBGR;
|
||||||
|
|
||||||
IFS(CoInitialize(NULL));
|
IFS(CoInitialize(NULL));
|
||||||
IFS(CoCreateInstance(MAKE_REFGUID(CLSID_WICImagingFactory), NULL,
|
IFS(CoCreateInstance(MAKE_REFGUID(CLSID_WICImagingFactory), NULL,
|
||||||
@ -130,11 +131,11 @@ static int WritePNG(const char* out_file_name,
|
|||||||
const uint32_t height = buffer->height;
|
const uint32_t height = buffer->height;
|
||||||
unsigned char* const rgb = buffer->u.RGBA.rgba;
|
unsigned char* const rgb = buffer->u.RGBA.rgba;
|
||||||
const int stride = buffer->u.RGBA.stride;
|
const int stride = buffer->u.RGBA.stride;
|
||||||
const int has_alpha = (buffer->colorspace == MODE_RGBA);
|
const int has_alpha = (buffer->colorspace == MODE_BGRA);
|
||||||
assert(!has_alpha); // TODO(mikolaj)
|
|
||||||
return SUCCEEDED(WriteUsingWIC(out_file_name,
|
return SUCCEEDED(WriteUsingWIC(out_file_name,
|
||||||
MAKE_REFGUID(GUID_ContainerFormatPng), rgb, stride, width,
|
MAKE_REFGUID(GUID_ContainerFormatPng), rgb, stride, width,
|
||||||
height));
|
height, has_alpha));
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(WEBP_HAVE_PNG) // !HAVE_WINCODEC_H
|
#elif defined(WEBP_HAVE_PNG) // !HAVE_WINCODEC_H
|
||||||
@ -266,7 +267,7 @@ static void SaveOutput(const WebPDecBuffer* const buffer,
|
|||||||
if (verbose)
|
if (verbose)
|
||||||
StopwatchReadAndReset(&stop_watch);
|
StopwatchReadAndReset(&stop_watch);
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef HAVE_WINCODEC_H
|
||||||
needs_open_file = (format != PNG);
|
needs_open_file = (format != PNG);
|
||||||
#endif
|
#endif
|
||||||
if (needs_open_file) {
|
if (needs_open_file) {
|
||||||
@ -431,9 +432,8 @@ int main(int argc, const char *argv[]) {
|
|||||||
|
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case PNG:
|
case PNG:
|
||||||
#ifdef _WIN32
|
#ifdef HAVE_WINCODEC_H
|
||||||
// TODO(mikolaj): no alpha for now
|
output_buffer->colorspace = bitstream->has_alpha ? MODE_BGRA : MODE_BGR;
|
||||||
output_buffer->colorspace = MODE_BGR;
|
|
||||||
#else
|
#else
|
||||||
output_buffer->colorspace = bitstream->has_alpha ? MODE_RGBA : MODE_RGB;
|
output_buffer->colorspace = bitstream->has_alpha ? MODE_RGBA : MODE_RGB;
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user