You've already forked wine-staging
mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-04-13 14:42:51 -07:00
Rebase against 152cda38df79cf04aae589f1d721de3cac1cd49e
This commit is contained in:
@@ -1,247 +0,0 @@
|
||||
From 663ca5c7923458a158ede7c01aa23805b5941ecc Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Timoshkov <dmitry@baikal.ru>
|
||||
Date: Thu, 20 Oct 2016 16:56:40 +0800
|
||||
Subject: windowscodecs: Add support for converting to 8bppIndexed format to
|
||||
IWICFormatConverter.
|
||||
|
||||
---
|
||||
dlls/windowscodecs/converter.c | 160 ++++++++++++++++++++++++++++++++++++-----
|
||||
1 file changed, 143 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/dlls/windowscodecs/converter.c b/dlls/windowscodecs/converter.c
|
||||
index 3704060..c6a2514 100644
|
||||
--- a/dlls/windowscodecs/converter.c
|
||||
+++ b/dlls/windowscodecs/converter.c
|
||||
@@ -76,7 +76,7 @@ typedef struct FormatConverter {
|
||||
const struct pixelformatinfo *dst_format, *src_format;
|
||||
WICBitmapDitherType dither;
|
||||
double alpha_threshold;
|
||||
- WICBitmapPaletteType palette_type;
|
||||
+ IWICPalette *palette;
|
||||
CRITICAL_SECTION lock; /* must be held when initialized */
|
||||
} FormatConverter;
|
||||
|
||||
@@ -1187,11 +1187,96 @@ static HRESULT copypixels_to_8bppGray(struct FormatConverter *This, const WICRec
|
||||
return hr;
|
||||
}
|
||||
|
||||
+static UINT rgb_to_palette_index(BYTE r, BYTE g, BYTE b, WICColor *colors, UINT count)
|
||||
+{
|
||||
+ UINT best_diff, best_index, i;
|
||||
+
|
||||
+ best_diff = ~0;
|
||||
+ best_index = 0;
|
||||
+
|
||||
+ for (i = 0; i < count; i++)
|
||||
+ {
|
||||
+ BYTE pal_r, pal_g, pal_b;
|
||||
+ DWORD diff_r, diff_g, diff_b, diff;
|
||||
+
|
||||
+ pal_r = colors[i] >> 16;
|
||||
+ pal_g = colors[i] >> 8;
|
||||
+ pal_b = colors[i];
|
||||
+
|
||||
+ diff_r = r - pal_r;
|
||||
+ diff_g = g - pal_g;
|
||||
+ diff_b = b - pal_b;
|
||||
+
|
||||
+ diff = diff_r * diff_r + diff_g * diff_g + diff_b * diff_b;
|
||||
+ if (diff == 0) return i;
|
||||
+
|
||||
+ if (diff < best_diff)
|
||||
+ {
|
||||
+ best_diff = diff;
|
||||
+ best_index = i;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return best_index;
|
||||
+}
|
||||
+
|
||||
+static HRESULT copypixels_to_8bppIndexed(struct FormatConverter *This, const WICRect *prc,
|
||||
+ UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
|
||||
+{
|
||||
+ HRESULT hr;
|
||||
+ BYTE *srcdata;
|
||||
+ WICColor colors[256];
|
||||
+ UINT srcstride, srcdatasize, count;
|
||||
+
|
||||
+ if (source_format == format_8bppIndexed)
|
||||
+ {
|
||||
+ if (prc)
|
||||
+ return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
|
||||
+
|
||||
+ return S_OK;
|
||||
+ }
|
||||
+
|
||||
+ if (!This->palette) return WINCODEC_ERR_WRONGSTATE;
|
||||
+
|
||||
+ hr = IWICPalette_GetColors(This->palette, 256, colors, &count);
|
||||
+ if (hr != S_OK) return hr;
|
||||
+ if (!count) return WINCODEC_ERR_WRONGSTATE;
|
||||
+
|
||||
+ srcstride = 3 * prc->Width;
|
||||
+ srcdatasize = srcstride * prc->Height;
|
||||
+
|
||||
+ srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize);
|
||||
+ if (!srcdata) return E_OUTOFMEMORY;
|
||||
+
|
||||
+ hr = copypixels_to_24bppBGR(This, prc, srcstride, srcdatasize, srcdata, source_format);
|
||||
+ if (SUCCEEDED(hr) && prc)
|
||||
+ {
|
||||
+ INT x, y;
|
||||
+ BYTE *src = srcdata, *dst = pbBuffer;
|
||||
+
|
||||
+ for (y = 0; y < prc->Height; y++)
|
||||
+ {
|
||||
+ BYTE *bgr = src;
|
||||
+
|
||||
+ for (x = 0; x < prc->Width; x++)
|
||||
+ {
|
||||
+ dst[x] = rgb_to_palette_index(bgr[2], bgr[1], bgr[0], colors, count);
|
||||
+ bgr += 3;
|
||||
+ }
|
||||
+ src += srcstride;
|
||||
+ dst += cbStride;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ HeapFree(GetProcessHeap(), 0, srcdata);
|
||||
+ return hr;
|
||||
+}
|
||||
+
|
||||
static const struct pixelformatinfo supported_formats[] = {
|
||||
{format_1bppIndexed, &GUID_WICPixelFormat1bppIndexed, NULL},
|
||||
{format_2bppIndexed, &GUID_WICPixelFormat2bppIndexed, NULL},
|
||||
{format_4bppIndexed, &GUID_WICPixelFormat4bppIndexed, NULL},
|
||||
- {format_8bppIndexed, &GUID_WICPixelFormat8bppIndexed, NULL},
|
||||
+ {format_8bppIndexed, &GUID_WICPixelFormat8bppIndexed, copypixels_to_8bppIndexed},
|
||||
{format_BlackWhite, &GUID_WICPixelFormatBlackWhite, NULL},
|
||||
{format_2bppGray, &GUID_WICPixelFormat2bppGray, NULL},
|
||||
{format_4bppGray, &GUID_WICPixelFormat4bppGray, NULL},
|
||||
@@ -1268,6 +1353,7 @@ static ULONG WINAPI FormatConverter_Release(IWICFormatConverter *iface)
|
||||
This->lock.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&This->lock);
|
||||
if (This->source) IWICBitmapSource_Release(This->source);
|
||||
+ if (This->palette) IWICPalette_Release(This->palette);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
@@ -1316,10 +1402,16 @@ static HRESULT WINAPI FormatConverter_GetResolution(IWICFormatConverter *iface,
|
||||
}
|
||||
|
||||
static HRESULT WINAPI FormatConverter_CopyPalette(IWICFormatConverter *iface,
|
||||
- IWICPalette *pIPalette)
|
||||
+ IWICPalette *palette)
|
||||
{
|
||||
- FIXME("(%p,%p): stub\n", iface, pIPalette);
|
||||
- return E_NOTIMPL;
|
||||
+ FormatConverter *This = impl_from_IWICFormatConverter(iface);
|
||||
+
|
||||
+ TRACE("(%p,%p)\n", iface, palette);
|
||||
+
|
||||
+ if (!palette) return E_INVALIDARG;
|
||||
+ if (!This->palette) return WINCODEC_ERR_WRONGSTATE;
|
||||
+
|
||||
+ return IWICPalette_InitializeFromPalette(palette, This->palette);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI FormatConverter_CopyPixels(IWICFormatConverter *iface,
|
||||
@@ -1352,19 +1444,52 @@ static HRESULT WINAPI FormatConverter_CopyPixels(IWICFormatConverter *iface,
|
||||
}
|
||||
|
||||
static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface,
|
||||
- IWICBitmapSource *pISource, REFWICPixelFormatGUID dstFormat, WICBitmapDitherType dither,
|
||||
- IWICPalette *pIPalette, double alphaThresholdPercent, WICBitmapPaletteType paletteTranslate)
|
||||
+ IWICBitmapSource *source, REFWICPixelFormatGUID dstFormat, WICBitmapDitherType dither,
|
||||
+ IWICPalette *palette, double alpha_threshold, WICBitmapPaletteType palette_type)
|
||||
{
|
||||
FormatConverter *This = impl_from_IWICFormatConverter(iface);
|
||||
const struct pixelformatinfo *srcinfo, *dstinfo;
|
||||
- static INT fixme=0;
|
||||
GUID srcFormat;
|
||||
- HRESULT res=S_OK;
|
||||
+ HRESULT res;
|
||||
+
|
||||
+ TRACE("(%p,%p,%s,%u,%p,%0.3f,%u)\n", iface, source, debugstr_guid(dstFormat),
|
||||
+ dither, palette, alpha_threshold, palette_type);
|
||||
+
|
||||
+ if (!palette)
|
||||
+ {
|
||||
+ res = PaletteImpl_Create(&palette);
|
||||
+ if (res != S_OK) return res;
|
||||
+
|
||||
+ switch (palette_type)
|
||||
+ {
|
||||
+ case WICBitmapPaletteTypeCustom:
|
||||
+ IWICPalette_Release(palette);
|
||||
+ palette = NULL;
|
||||
+ res = S_OK;
|
||||
+ break;
|
||||
+
|
||||
+ case WICBitmapPaletteTypeMedianCut:
|
||||
+ {
|
||||
+ UINT bpp;
|
||||
+ res = get_pixelformat_bpp(dstFormat, &bpp);
|
||||
+ if (res == S_OK && bpp <= 8)
|
||||
+ res = IWICPalette_InitializeFromBitmap(palette, source, 1 << bpp, FALSE);
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
- TRACE("(%p,%p,%s,%u,%p,%0.1f,%u)\n", iface, pISource, debugstr_guid(dstFormat),
|
||||
- dither, pIPalette, alphaThresholdPercent, paletteTranslate);
|
||||
+ default:
|
||||
+ res = IWICPalette_InitializePredefined(palette, palette_type, FALSE);
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
- if (pIPalette && !fixme++) FIXME("ignoring palette\n");
|
||||
+ if (res != S_OK)
|
||||
+ {
|
||||
+ IWICPalette_Release(palette);
|
||||
+ return res;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ IWICPalette_AddRef(palette);
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
@@ -1374,7 +1499,7 @@ static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface,
|
||||
goto end;
|
||||
}
|
||||
|
||||
- res = IWICBitmapSource_GetPixelFormat(pISource, &srcFormat);
|
||||
+ res = IWICBitmapSource_GetPixelFormat(source, &srcFormat);
|
||||
if (FAILED(res)) goto end;
|
||||
|
||||
srcinfo = get_formatinfo(&srcFormat);
|
||||
@@ -1395,13 +1520,13 @@ static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface,
|
||||
|
||||
if (dstinfo->copy_function)
|
||||
{
|
||||
- IWICBitmapSource_AddRef(pISource);
|
||||
+ IWICBitmapSource_AddRef(source);
|
||||
This->src_format = srcinfo;
|
||||
This->dst_format = dstinfo;
|
||||
This->dither = dither;
|
||||
- This->alpha_threshold = alphaThresholdPercent;
|
||||
- This->palette_type = paletteTranslate;
|
||||
- This->source = pISource;
|
||||
+ This->alpha_threshold = alpha_threshold;
|
||||
+ This->palette = palette;
|
||||
+ This->source = source;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1480,6 +1605,7 @@ HRESULT FormatConverter_CreateInstance(REFIID iid, void** ppv)
|
||||
This->IWICFormatConverter_iface.lpVtbl = &FormatConverter_Vtbl;
|
||||
This->ref = 1;
|
||||
This->source = NULL;
|
||||
+ This->palette = NULL;
|
||||
InitializeCriticalSection(&This->lock);
|
||||
This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": FormatConverter.lock");
|
||||
|
||||
--
|
||||
2.9.0
|
||||
|
Reference in New Issue
Block a user