[WINDOWSCODECS] Sync with Wine Staging 3.3. CORE-14434

This commit is contained in:
Amine Khaldi 2018-03-05 00:19:05 +01:00
parent a8d718da39
commit ae80686d81
34 changed files with 3112 additions and 380 deletions

View file

@ -1,5 +1,6 @@
/*
* Copyright 2009 Vincent Povirk for CodeWeavers
* Copyright 2016 Dmitry Timoshkov
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -16,13 +17,28 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include <stdarg.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "wingdi.h"
#include "objbase.h"
#include "wincodecs_private.h"
#include <wingdi.h>
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
struct bmp_pixelformat {
const WICPixelFormatGUID *guid;
UINT bpp;
UINT colors; /* palette size */
DWORD compression;
DWORD redmask;
DWORD greenmask;
@ -31,13 +47,18 @@ struct bmp_pixelformat {
};
static const struct bmp_pixelformat formats[] = {
{&GUID_WICPixelFormat24bppBGR, 24, BI_RGB},
{&GUID_WICPixelFormat16bppBGR555, 16, BI_RGB},
{&GUID_WICPixelFormat16bppBGR565, 16, BI_BITFIELDS, 0xf800, 0x7e0, 0x1f, 0},
{&GUID_WICPixelFormat32bppBGR, 32, BI_RGB},
{&GUID_WICPixelFormat24bppBGR, 24, 0, BI_RGB},
{&GUID_WICPixelFormatBlackWhite, 1, 2, BI_RGB},
{&GUID_WICPixelFormat1bppIndexed, 1, 2, BI_RGB},
{&GUID_WICPixelFormat2bppIndexed, 2, 4, BI_RGB},
{&GUID_WICPixelFormat4bppIndexed, 4, 16, BI_RGB},
{&GUID_WICPixelFormat8bppIndexed, 8, 256, BI_RGB},
{&GUID_WICPixelFormat16bppBGR555, 16, 0, BI_RGB},
{&GUID_WICPixelFormat16bppBGR565, 16, 0, BI_BITFIELDS, 0xf800, 0x7e0, 0x1f, 0},
{&GUID_WICPixelFormat32bppBGR, 32, 0, BI_RGB},
#if 0
/* Windows doesn't seem to support this one. */
{&GUID_WICPixelFormat32bppBGRA, 32, BI_BITFIELDS, 0xff0000, 0xff00, 0xff, 0xff000000},
{&GUID_WICPixelFormat32bppBGRA, 32, 0, BI_BITFIELDS, 0xff0000, 0xff00, 0xff, 0xff000000},
#endif
{NULL}
};
@ -58,6 +79,8 @@ typedef struct BmpFrameEncode {
BOOL committed;
} BmpFrameEncode;
static const WCHAR wszEnableV5Header32bppBGRA[] = {'E','n','a','b','l','e','V','5','H','e','a','d','e','r','3','2','b','p','p','B','G','R','A',0};
static inline BmpFrameEncode *impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEncode *iface)
{
return CONTAINING_RECORD(iface, BmpFrameEncode, IWICBitmapFrameEncode_iface);
@ -121,6 +144,9 @@ static HRESULT WINAPI BmpFrameEncode_Initialize(IWICBitmapFrameEncode *iface,
if (This->initialized) return WINCODEC_ERR_WRONGSTATE;
if (pIEncoderOptions)
WARN("ignoring encoder options.\n");
This->initialized = TRUE;
return S_OK;
@ -165,11 +191,13 @@ static HRESULT WINAPI BmpFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface
for (i=0; formats[i].guid; i++)
{
if (memcmp(formats[i].guid, pPixelFormat, sizeof(GUID)) == 0)
if (IsEqualGUID(formats[i].guid, pPixelFormat))
break;
}
if (!formats[i].guid) i = 0;
else if (IsEqualGUID(pPixelFormat, &GUID_WICPixelFormatBlackWhite))
i = 2; /* GUID_WICPixelFormat1bppIndexed */
This->format = &formats[i];
memcpy(pPixelFormat, This->format->guid, sizeof(GUID));
@ -188,6 +216,7 @@ static HRESULT WINAPI BmpFrameEncode_SetPalette(IWICBitmapFrameEncode *iface,
IWICPalette *palette)
{
BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
HRESULT hr;
TRACE("(%p,%p)\n", iface, palette);
@ -196,7 +225,14 @@ static HRESULT WINAPI BmpFrameEncode_SetPalette(IWICBitmapFrameEncode *iface,
if (!This->initialized)
return WINCODEC_ERR_NOTINITIALIZED;
return IWICPalette_GetColors(palette, 256, This->palette, &This->colors);
hr = IWICPalette_GetColors(palette, 256, This->palette, &This->colors);
if (hr == S_OK)
{
UINT i;
for (i = 0; i < This->colors; i++)
This->palette[i] |= 0xff000000; /* BMP palette has no alpha */
}
return hr;
}
static HRESULT WINAPI BmpFrameEncode_SetThumbnail(IWICBitmapFrameEncode *iface,
@ -278,10 +314,11 @@ static HRESULT WINAPI BmpFrameEncode_Commit(IWICBitmapFrameEncode *iface)
BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
BITMAPFILEHEADER bfh;
BITMAPV5HEADER bih;
UINT info_size;
UINT info_size, i;
LARGE_INTEGER pos;
ULONG byteswritten;
HRESULT hr;
const BYTE *bits;
TRACE("(%p)\n", iface);
@ -294,15 +331,15 @@ static HRESULT WINAPI BmpFrameEncode_Commit(IWICBitmapFrameEncode *iface)
bih.bV5Size = info_size = sizeof(BITMAPINFOHEADER);
bih.bV5Width = This->width;
bih.bV5Height = -This->height; /* top-down bitmap */
bih.bV5Height = This->height; /* bottom-top bitmap */
bih.bV5Planes = 1;
bih.bV5BitCount = This->format->bpp;
bih.bV5Compression = This->format->compression;
bih.bV5SizeImage = This->stride*This->height;
bih.bV5XPelsPerMeter = (This->xres+0.0127) / 0.0254;
bih.bV5YPelsPerMeter = (This->yres+0.0127) / 0.0254;
bih.bV5ClrUsed = 0;
bih.bV5ClrImportant = 0;
bih.bV5ClrUsed = (This->format->bpp <= 8) ? This->colors : 0;
bih.bV5ClrImportant = bih.bV5ClrUsed;
if (This->format->compression == BI_BITFIELDS)
{
@ -319,6 +356,7 @@ static HRESULT WINAPI BmpFrameEncode_Commit(IWICBitmapFrameEncode *iface)
bfh.bfSize = sizeof(BITMAPFILEHEADER) + info_size + bih.bV5SizeImage;
bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + info_size;
bfh.bfOffBits += bih.bV5ClrUsed * sizeof(WICColor);
pos.QuadPart = 0;
hr = IStream_Seek(This->stream, pos, STREAM_SEEK_SET, NULL);
@ -332,9 +370,23 @@ static HRESULT WINAPI BmpFrameEncode_Commit(IWICBitmapFrameEncode *iface)
if (FAILED(hr)) return hr;
if (byteswritten != info_size) return E_FAIL;
hr = IStream_Write(This->stream, This->bits, bih.bV5SizeImage, &byteswritten);
if (FAILED(hr)) return hr;
if (byteswritten != bih.bV5SizeImage) return E_FAIL;
/* write the palette */
if (This->format->colors)
{
hr = IStream_Write(This->stream, This->palette, This->colors * sizeof(WICColor), &byteswritten);
if (FAILED(hr)) return hr;
if (byteswritten != This->colors * sizeof(WICColor)) return E_FAIL;
}
/* write the image bits as a bottom-top array */
bits = This->bits + bih.bV5SizeImage;
for (i = 0; i < This->height; i++)
{
bits -= This->stride;
hr = IStream_Write(This->stream, bits, This->stride, &byteswritten);
if (FAILED(hr)) return hr;
if (byteswritten != This->stride) return E_FAIL;
}
This->committed = TRUE;
@ -447,11 +499,22 @@ static HRESULT WINAPI BmpEncoder_GetContainerFormat(IWICBitmapEncoder *iface,
return S_OK;
}
static HRESULT WINAPI BmpEncoder_GetEncoderInfo(IWICBitmapEncoder *iface,
IWICBitmapEncoderInfo **ppIEncoderInfo)
static HRESULT WINAPI BmpEncoder_GetEncoderInfo(IWICBitmapEncoder *iface, IWICBitmapEncoderInfo **info)
{
FIXME("(%p,%p): stub\n", iface, ppIEncoderInfo);
return E_NOTIMPL;
IWICComponentInfo *comp_info;
HRESULT hr;
TRACE("%p,%p\n", iface, info);
if (!info) return E_INVALIDARG;
hr = CreateComponentInfo(&CLSID_WICBmpEncoder, &comp_info);
if (hr == S_OK)
{
hr = IWICComponentInfo_QueryInterface(comp_info, &IID_IWICBitmapEncoderInfo, (void **)info);
IWICComponentInfo_Release(comp_info);
}
return hr;
}
static HRESULT WINAPI BmpEncoder_SetColorContexts(IWICBitmapEncoder *iface,
@ -487,6 +550,10 @@ static HRESULT WINAPI BmpEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
BmpEncoder *This = impl_from_IWICBitmapEncoder(iface);
BmpFrameEncode *encode;
HRESULT hr;
static const PROPBAG2 opts[1] =
{
{ PROPBAG2_TYPE_DATA, VT_BOOL, 0, 0, (LPOLESTR)wszEnableV5Header32bppBGRA },
};
TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions);
@ -494,8 +561,11 @@ static HRESULT WINAPI BmpEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
if (!This->stream) return WINCODEC_ERR_NOTINITIALIZED;
hr = CreatePropertyBag2(NULL, 0, ppIEncoderOptions);
if (FAILED(hr)) return hr;
if (ppIEncoderOptions)
{
hr = CreatePropertyBag2(opts, sizeof(opts)/sizeof(opts[0]), ppIEncoderOptions);
if (FAILED(hr)) return hr;
}
encode = HeapAlloc(GetProcessHeap(), 0, sizeof(BmpFrameEncode));
if (!encode)