mirror of
https://github.com/reactos/reactos.git
synced 2024-12-31 19:42:51 +00:00
[WINDOWSCODECS] Sync with Wine Staging 1.9.23. CORE-12409
svn path=/trunk/; revision=73303
This commit is contained in:
parent
8209287044
commit
c3af8cc0b7
19 changed files with 1866 additions and 206 deletions
|
@ -256,7 +256,7 @@ static HRESULT WINAPI BmpFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface,
|
|||
if (This->bih.bV5ClrUsed == 0)
|
||||
count = 1 << This->bih.bV5BitCount;
|
||||
else
|
||||
count = This->bih.bV5ClrUsed;
|
||||
count = min(This->bih.bV5ClrUsed, 1 << This->bih.bV5BitCount);
|
||||
|
||||
tablesize = sizeof(WICColor) * count;
|
||||
wiccolors = HeapAlloc(GetProcessHeap(), 0, tablesize);
|
||||
|
|
|
@ -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
|
||||
|
@ -23,6 +24,7 @@
|
|||
struct bmp_pixelformat {
|
||||
const WICPixelFormatGUID *guid;
|
||||
UINT bpp;
|
||||
UINT colors; /* palette size */
|
||||
DWORD compression;
|
||||
DWORD redmask;
|
||||
DWORD greenmask;
|
||||
|
@ -31,13 +33,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}
|
||||
};
|
||||
|
@ -53,6 +60,8 @@ typedef struct BmpFrameEncode {
|
|||
double xres, yres;
|
||||
UINT lineswritten;
|
||||
UINT stride;
|
||||
WICColor palette[256];
|
||||
UINT colors;
|
||||
BOOL committed;
|
||||
} BmpFrameEncode;
|
||||
|
||||
|
@ -163,11 +172,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));
|
||||
|
@ -183,10 +194,26 @@ static HRESULT WINAPI BmpFrameEncode_SetColorContexts(IWICBitmapFrameEncode *ifa
|
|||
}
|
||||
|
||||
static HRESULT WINAPI BmpFrameEncode_SetPalette(IWICBitmapFrameEncode *iface,
|
||||
IWICPalette *pIPalette)
|
||||
IWICPalette *palette)
|
||||
{
|
||||
FIXME("(%p,%p): stub\n", iface, pIPalette);
|
||||
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
|
||||
BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p)\n", iface, palette);
|
||||
|
||||
if (!palette) return E_INVALIDARG;
|
||||
|
||||
if (!This->initialized)
|
||||
return WINCODEC_ERR_NOTINITIALIZED;
|
||||
|
||||
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,
|
||||
|
@ -268,10 +295,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);
|
||||
|
||||
|
@ -284,15 +312,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)
|
||||
{
|
||||
|
@ -309,6 +337,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);
|
||||
|
@ -322,9 +351,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;
|
||||
|
||||
|
@ -437,11 +480,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,
|
||||
|
@ -451,10 +505,12 @@ static HRESULT WINAPI BmpEncoder_SetColorContexts(IWICBitmapEncoder *iface,
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI BmpEncoder_SetPalette(IWICBitmapEncoder *iface, IWICPalette *pIPalette)
|
||||
static HRESULT WINAPI BmpEncoder_SetPalette(IWICBitmapEncoder *iface, IWICPalette *palette)
|
||||
{
|
||||
TRACE("(%p,%p)\n", iface, pIPalette);
|
||||
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
|
||||
BmpEncoder *This = impl_from_IWICBitmapEncoder(iface);
|
||||
|
||||
TRACE("(%p,%p)\n", iface, palette);
|
||||
return This->stream ? WINCODEC_ERR_UNSUPPORTEDOPERATION : WINCODEC_ERR_NOTINITIALIZED;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI BmpEncoder_SetThumbnail(IWICBitmapEncoder *iface, IWICBitmapSource *pIThumbnail)
|
||||
|
@ -504,6 +560,7 @@ static HRESULT WINAPI BmpEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
|
|||
encode->xres = 0.0;
|
||||
encode->yres = 0.0;
|
||||
encode->lineswritten = 0;
|
||||
encode->colors = 0;
|
||||
encode->committed = FALSE;
|
||||
|
||||
*ppIFrameEncode = &encode->IWICBitmapFrameEncode_iface;
|
||||
|
|
|
@ -32,6 +32,7 @@ static const classinfo wic_classes[] = {
|
|||
{&CLSID_WICPngEncoder, PngEncoder_CreateInstance},
|
||||
{&CLSID_WICBmpEncoder, BmpEncoder_CreateInstance},
|
||||
{&CLSID_WICGifDecoder, GifDecoder_CreateInstance},
|
||||
{&CLSID_WICGifEncoder, GifEncoder_CreateInstance},
|
||||
{&CLSID_WICIcoDecoder, IcoDecoder_CreateInstance},
|
||||
{&CLSID_WICJpegDecoder, JpegDecoder_CreateInstance},
|
||||
{&CLSID_WICJpegEncoder, JpegEncoder_CreateInstance},
|
||||
|
|
|
@ -63,7 +63,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;
|
||||
|
||||
|
@ -91,7 +91,7 @@ static void from_sRGB(BYTE *bgr)
|
|||
|
||||
r = from_sRGB_component(r);
|
||||
g = from_sRGB_component(g);
|
||||
g = from_sRGB_component(b);
|
||||
b = from_sRGB_component(b);
|
||||
|
||||
bgr[2] = (BYTE)(r * 255.0f);
|
||||
bgr[1] = (BYTE)(g * 255.0f);
|
||||
|
@ -108,7 +108,7 @@ static void to_sRGB(BYTE *bgr)
|
|||
|
||||
r = to_sRGB_component(r);
|
||||
g = to_sRGB_component(g);
|
||||
g = to_sRGB_component(b);
|
||||
b = to_sRGB_component(b);
|
||||
|
||||
bgr[2] = (BYTE)(r * 255.0f);
|
||||
bgr[1] = (BYTE)(g * 255.0f);
|
||||
|
@ -244,7 +244,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe
|
|||
*dstpixel++ = colors[srcval>>6];
|
||||
if (x+1 < prc->Width) *dstpixel++ = colors[srcval>>4&0x3];
|
||||
if (x+2 < prc->Width) *dstpixel++ = colors[srcval>>2&0x3];
|
||||
if (x+1 < prc->Width) *dstpixel++ = colors[srcval&0x3];
|
||||
if (x+3 < prc->Width) *dstpixel++ = colors[srcval&0x3];
|
||||
}
|
||||
srcrow += srcstride;
|
||||
dstrow += cbStride;
|
||||
|
@ -1035,6 +1035,7 @@ static HRESULT copypixels_to_24bppRGB(struct FormatConverter *This, const WICRec
|
|||
const BYTE *srcpixel;
|
||||
BYTE *dstrow;
|
||||
BYTE *dstpixel;
|
||||
BYTE tmppixel[3];
|
||||
|
||||
srcstride = 4 * prc->Width;
|
||||
srcdatasize = srcstride * prc->Height;
|
||||
|
@ -1052,16 +1053,18 @@ static HRESULT copypixels_to_24bppRGB(struct FormatConverter *This, const WICRec
|
|||
srcpixel=srcrow;
|
||||
dstpixel=dstrow;
|
||||
for (x=0; x<prc->Width; x++) {
|
||||
*dstpixel++=*srcpixel++; /* blue */
|
||||
*dstpixel++=*srcpixel++; /* green */
|
||||
*dstpixel++=*srcpixel++; /* red */
|
||||
tmppixel[0]=*srcpixel++; /* blue */
|
||||
tmppixel[1]=*srcpixel++; /* green */
|
||||
tmppixel[2]=*srcpixel++; /* red */
|
||||
srcpixel++; /* alpha */
|
||||
|
||||
*dstpixel++=tmppixel[2]; /* red */
|
||||
*dstpixel++=tmppixel[1]; /* green */
|
||||
*dstpixel++=tmppixel[0]; /* blue */
|
||||
}
|
||||
srcrow += srcstride;
|
||||
dstrow += cbStride;
|
||||
}
|
||||
|
||||
reverse_bgr8(3, pbBuffer, prc->Width, prc->Height, cbStride);
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, srcdata);
|
||||
|
@ -1171,11 +1174,95 @@ 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;
|
||||
|
||||
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},
|
||||
|
@ -1252,6 +1339,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);
|
||||
}
|
||||
|
||||
|
@ -1276,7 +1364,7 @@ static HRESULT WINAPI FormatConverter_GetPixelFormat(IWICFormatConverter *iface,
|
|||
{
|
||||
FormatConverter *This = impl_from_IWICFormatConverter(iface);
|
||||
|
||||
TRACE("(%p,%p): stub\n", iface, pPixelFormat);
|
||||
TRACE("(%p,%p)\n", iface, pPixelFormat);
|
||||
|
||||
if (This->source)
|
||||
memcpy(pPixelFormat, This->dst_format->guid, sizeof(GUID));
|
||||
|
@ -1291,7 +1379,7 @@ static HRESULT WINAPI FormatConverter_GetResolution(IWICFormatConverter *iface,
|
|||
{
|
||||
FormatConverter *This = impl_from_IWICFormatConverter(iface);
|
||||
|
||||
TRACE("(%p,%p,%p): stub\n", iface, pDpiX, pDpiY);
|
||||
TRACE("(%p,%p,%p)\n", iface, pDpiX, pDpiY);
|
||||
|
||||
if (This->source)
|
||||
return IWICBitmapSource_GetResolution(This->source, pDpiX, pDpiY);
|
||||
|
@ -1300,10 +1388,27 @@ 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->source) return WINCODEC_ERR_WRONGSTATE;
|
||||
|
||||
if (!This->palette)
|
||||
{
|
||||
HRESULT hr;
|
||||
UINT bpp;
|
||||
|
||||
hr = get_pixelformat_bpp(This->dst_format->guid, &bpp);
|
||||
if (hr != S_OK) return hr;
|
||||
if (bpp <= 8) return WINCODEC_ERR_WRONGSTATE;
|
||||
return IWICBitmapSource_CopyPalette(This->source, palette);
|
||||
}
|
||||
|
||||
return IWICPalette_InitializeFromPalette(palette, This->palette);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI FormatConverter_CopyPixels(IWICFormatConverter *iface,
|
||||
|
@ -1332,23 +1437,59 @@ static HRESULT WINAPI FormatConverter_CopyPixels(IWICFormatConverter *iface,
|
|||
pbBuffer, This->src_format->format);
|
||||
}
|
||||
else
|
||||
return WINCODEC_ERR_NOTINITIALIZED;
|
||||
return WINCODEC_ERR_WRONGSTATE;
|
||||
}
|
||||
|
||||
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.1f,%u)\n", iface, pISource, debugstr_guid(dstFormat),
|
||||
dither, pIPalette, alphaThresholdPercent, paletteTranslate);
|
||||
TRACE("(%p,%p,%s,%u,%p,%0.3f,%u)\n", iface, source, debugstr_guid(dstFormat),
|
||||
dither, palette, alpha_threshold, palette_type);
|
||||
|
||||
if (pIPalette && !fixme++) FIXME("ignoring palette\n");
|
||||
if (!palette)
|
||||
{
|
||||
UINT bpp;
|
||||
res = get_pixelformat_bpp(dstFormat, &bpp);
|
||||
if (res != S_OK) return res;
|
||||
|
||||
res = PaletteImpl_Create(&palette);
|
||||
if (res != S_OK) return res;
|
||||
|
||||
switch (palette_type)
|
||||
{
|
||||
case WICBitmapPaletteTypeCustom:
|
||||
IWICPalette_Release(palette);
|
||||
palette = NULL;
|
||||
if (bpp <= 8) return E_INVALIDARG;
|
||||
break;
|
||||
|
||||
case WICBitmapPaletteTypeMedianCut:
|
||||
{
|
||||
if (bpp <= 8)
|
||||
res = IWICPalette_InitializeFromBitmap(palette, source, 1 << bpp, FALSE);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
if (bpp <= 8)
|
||||
res = IWICPalette_InitializePredefined(palette, palette_type, FALSE);
|
||||
break;
|
||||
}
|
||||
|
||||
if (res != S_OK)
|
||||
{
|
||||
IWICPalette_Release(palette);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
else
|
||||
IWICPalette_AddRef(palette);
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
|
@ -1358,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);
|
||||
|
@ -1379,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
|
||||
{
|
||||
|
@ -1397,6 +1538,9 @@ end:
|
|||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
if (res != S_OK && palette)
|
||||
IWICPalette_Release(palette);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -1464,6 +1608,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");
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -399,7 +399,7 @@ static HRESULT WINAPI IcnsFrameEncode_Commit(IWICBitmapFrameEncode *iface)
|
|||
OSErr ret;
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
TRACE("(%p): stub\n", iface);
|
||||
TRACE("(%p)\n", iface);
|
||||
|
||||
EnterCriticalSection(&This->encoder->lock);
|
||||
|
||||
|
|
|
@ -104,22 +104,23 @@ static HRESULT WINAPI ComponentFactory_CreateDecoderFromFilename(
|
|||
return hr;
|
||||
}
|
||||
|
||||
static IWICBitmapDecoder *find_decoder(IStream *pIStream, const GUID *pguidVendor,
|
||||
WICDecodeOptions metadataOptions)
|
||||
static HRESULT find_decoder(IStream *pIStream, const GUID *pguidVendor,
|
||||
WICDecodeOptions metadataOptions, IWICBitmapDecoder **decoder)
|
||||
{
|
||||
IEnumUnknown *enumdecoders;
|
||||
IUnknown *unkdecoderinfo;
|
||||
IWICBitmapDecoderInfo *decoderinfo;
|
||||
IWICBitmapDecoder *decoder = NULL;
|
||||
GUID vendor;
|
||||
HRESULT res;
|
||||
ULONG num_fetched;
|
||||
BOOL matches;
|
||||
|
||||
res = CreateComponentEnumerator(WICDecoder, WICComponentEnumerateDefault, &enumdecoders);
|
||||
if (FAILED(res)) return NULL;
|
||||
*decoder = NULL;
|
||||
|
||||
while (!decoder)
|
||||
res = CreateComponentEnumerator(WICDecoder, WICComponentEnumerateDefault, &enumdecoders);
|
||||
if (FAILED(res)) return res;
|
||||
|
||||
while (!*decoder)
|
||||
{
|
||||
res = IEnumUnknown_Next(enumdecoders, 1, &unkdecoderinfo, &num_fetched);
|
||||
|
||||
|
@ -144,18 +145,21 @@ static IWICBitmapDecoder *find_decoder(IStream *pIStream, const GUID *pguidVendo
|
|||
|
||||
if (SUCCEEDED(res) && matches)
|
||||
{
|
||||
res = IWICBitmapDecoderInfo_CreateInstance(decoderinfo, &decoder);
|
||||
res = IWICBitmapDecoderInfo_CreateInstance(decoderinfo, decoder);
|
||||
|
||||
/* FIXME: should use QueryCapability to choose a decoder */
|
||||
|
||||
if (SUCCEEDED(res))
|
||||
{
|
||||
res = IWICBitmapDecoder_Initialize(decoder, pIStream, metadataOptions);
|
||||
res = IWICBitmapDecoder_Initialize(*decoder, pIStream, metadataOptions);
|
||||
|
||||
if (FAILED(res))
|
||||
{
|
||||
IWICBitmapDecoder_Release(decoder);
|
||||
decoder = NULL;
|
||||
IWICBitmapDecoder_Release(*decoder);
|
||||
IWICBitmapDecoderInfo_Release(decoderinfo);
|
||||
IUnknown_Release(unkdecoderinfo);
|
||||
*decoder = NULL;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -171,7 +175,7 @@ static IWICBitmapDecoder *find_decoder(IStream *pIStream, const GUID *pguidVendo
|
|||
|
||||
IEnumUnknown_Release(enumdecoders);
|
||||
|
||||
return decoder;
|
||||
return WINCODEC_ERR_COMPONENTNOTFOUND;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ComponentFactory_CreateDecoderFromStream(
|
||||
|
@ -185,9 +189,9 @@ static HRESULT WINAPI ComponentFactory_CreateDecoderFromStream(
|
|||
metadataOptions, ppIDecoder);
|
||||
|
||||
if (pguidVendor)
|
||||
decoder = find_decoder(pIStream, pguidVendor, metadataOptions);
|
||||
res = find_decoder(pIStream, pguidVendor, metadataOptions, &decoder);
|
||||
if (!decoder)
|
||||
decoder = find_decoder(pIStream, NULL, metadataOptions);
|
||||
res = find_decoder(pIStream, NULL, metadataOptions, &decoder);
|
||||
|
||||
if (decoder)
|
||||
{
|
||||
|
@ -202,17 +206,17 @@ static HRESULT WINAPI ComponentFactory_CreateDecoderFromStream(
|
|||
BYTE data[4];
|
||||
ULONG bytesread;
|
||||
|
||||
WARN("failed to load from a stream\n");
|
||||
WARN("failed to load from a stream %#x\n", res);
|
||||
|
||||
seek.QuadPart = 0;
|
||||
res = IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL);
|
||||
if (SUCCEEDED(res))
|
||||
res = IStream_Read(pIStream, data, 4, &bytesread);
|
||||
if (SUCCEEDED(res))
|
||||
WARN("first %i bytes of stream=%x %x %x %x\n", bytesread, data[0], data[1], data[2], data[3]);
|
||||
if (IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL) == S_OK)
|
||||
{
|
||||
if (IStream_Read(pIStream, data, 4, &bytesread) == S_OK)
|
||||
WARN("first %i bytes of stream=%x %x %x %x\n", bytesread, data[0], data[1], data[2], data[3]);
|
||||
}
|
||||
}
|
||||
*ppIDecoder = NULL;
|
||||
return WINCODEC_ERR_COMPONENTNOTFOUND;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -853,8 +853,12 @@ static HRESULT WINAPI BitmapEncoderInfo_GetMimeTypes(IWICBitmapEncoderInfo *ifac
|
|||
static HRESULT WINAPI BitmapEncoderInfo_GetFileExtensions(IWICBitmapEncoderInfo *iface,
|
||||
UINT cchFileExtensions, WCHAR *wzFileExtensions, UINT *pcchActual)
|
||||
{
|
||||
FIXME("(%p,%u,%p,%p): stub\n", iface, cchFileExtensions, wzFileExtensions, pcchActual);
|
||||
return E_NOTIMPL;
|
||||
BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
|
||||
|
||||
TRACE("(%p,%u,%p,%p)\n", iface, cchFileExtensions, wzFileExtensions, pcchActual);
|
||||
|
||||
return ComponentInfo_GetStringValue(This->classkey, fileextensions_valuename,
|
||||
cchFileExtensions, wzFileExtensions, pcchActual);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI BitmapEncoderInfo_DoesSupportAnimation(IWICBitmapEncoderInfo *iface,
|
||||
|
@ -2317,7 +2321,7 @@ HRESULT WINAPI WICConvertBitmapSource(REFWICPixelFormatGUID dstFormat, IWICBitma
|
|||
|
||||
if (SUCCEEDED(res) && canconvert)
|
||||
res = IWICFormatConverter_Initialize(converter, pISrc, dstFormat, WICBitmapDitherTypeNone,
|
||||
NULL, 0.0, WICBitmapPaletteTypeCustom);
|
||||
NULL, 0.0, WICBitmapPaletteTypeMedianCut);
|
||||
|
||||
if (FAILED(res) || !canconvert)
|
||||
{
|
||||
|
|
|
@ -398,10 +398,14 @@ static HRESULT WINAPI JpegDecoder_CopyPalette(IWICBitmapDecoder *iface,
|
|||
}
|
||||
|
||||
static HRESULT WINAPI JpegDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface,
|
||||
IWICMetadataQueryReader **ppIMetadataQueryReader)
|
||||
IWICMetadataQueryReader **reader)
|
||||
{
|
||||
FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryReader);
|
||||
return E_NOTIMPL;
|
||||
FIXME("(%p,%p): stub\n", iface, reader);
|
||||
|
||||
if (!reader) return E_INVALIDARG;
|
||||
|
||||
*reader = NULL;
|
||||
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI JpegDecoder_GetPreview(IWICBitmapDecoder *iface,
|
||||
|
@ -843,6 +847,8 @@ typedef struct JpegEncoder {
|
|||
double xres, yres;
|
||||
const jpeg_compress_format *format;
|
||||
IStream *stream;
|
||||
WICColor palette[256];
|
||||
UINT colors;
|
||||
CRITICAL_SECTION lock;
|
||||
BYTE dest_buffer[1024];
|
||||
} JpegEncoder;
|
||||
|
@ -1045,10 +1051,24 @@ static HRESULT WINAPI JpegEncoder_Frame_SetColorContexts(IWICBitmapFrameEncode *
|
|||
}
|
||||
|
||||
static HRESULT WINAPI JpegEncoder_Frame_SetPalette(IWICBitmapFrameEncode *iface,
|
||||
IWICPalette *pIPalette)
|
||||
IWICPalette *palette)
|
||||
{
|
||||
FIXME("(%p,%p): stub\n", iface, pIPalette);
|
||||
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
|
||||
JpegEncoder *This = impl_from_IWICBitmapFrameEncode(iface);
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p)\n", iface, palette);
|
||||
|
||||
if (!palette) return E_INVALIDARG;
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
if (This->initialized)
|
||||
hr = IWICPalette_GetColors(palette, 256, This->palette, &This->colors);
|
||||
else
|
||||
hr = WINCODEC_ERR_NOTINITIALIZED;
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI JpegEncoder_Frame_SetThumbnail(IWICBitmapFrameEncode *iface,
|
||||
|
@ -1352,11 +1372,22 @@ static HRESULT WINAPI JpegEncoder_GetContainerFormat(IWICBitmapEncoder *iface,
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI JpegEncoder_GetEncoderInfo(IWICBitmapEncoder *iface,
|
||||
IWICBitmapEncoderInfo **ppIEncoderInfo)
|
||||
static HRESULT WINAPI JpegEncoder_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_WICJpegEncoder, &comp_info);
|
||||
if (hr == S_OK)
|
||||
{
|
||||
hr = IWICComponentInfo_QueryInterface(comp_info, &IID_IWICBitmapEncoderInfo, (void **)info);
|
||||
IWICComponentInfo_Release(comp_info);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI JpegEncoder_SetColorContexts(IWICBitmapEncoder *iface,
|
||||
|
@ -1406,11 +1437,14 @@ static HRESULT WINAPI JpegEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
|
|||
return WINCODEC_ERR_NOTINITIALIZED;
|
||||
}
|
||||
|
||||
hr = CreatePropertyBag2(NULL, 0, ppIEncoderOptions);
|
||||
if (FAILED(hr))
|
||||
if (ppIEncoderOptions)
|
||||
{
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return hr;
|
||||
hr = CreatePropertyBag2(NULL, 0, ppIEncoderOptions);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
This->frame_count = 1;
|
||||
|
@ -1498,6 +1532,7 @@ HRESULT JpegEncoder_CreateInstance(REFIID iid, void** ppv)
|
|||
This->xres = This->yres = 0.0;
|
||||
This->format = NULL;
|
||||
This->stream = NULL;
|
||||
This->colors = 0;
|
||||
InitializeCriticalSection(&This->lock);
|
||||
This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": JpegEncoder.lock");
|
||||
|
||||
|
|
|
@ -103,6 +103,12 @@ HRESULT copy_pixels(UINT bpp, const BYTE *srcbuffer,
|
|||
}
|
||||
}
|
||||
|
||||
static BOOL is_1bpp_format(const WICPixelFormatGUID *format)
|
||||
{
|
||||
return IsEqualGUID(format, &GUID_WICPixelFormatBlackWhite) ||
|
||||
IsEqualGUID(format, &GUID_WICPixelFormat1bppIndexed);
|
||||
}
|
||||
|
||||
HRESULT configure_write_source(IWICBitmapFrameEncode *iface,
|
||||
IWICBitmapSource *source, const WICRect *prc,
|
||||
const WICPixelFormatGUID *format,
|
||||
|
@ -127,11 +133,11 @@ HRESULT configure_write_source(IWICBitmapFrameEncode *iface,
|
|||
format = &dst_format;
|
||||
}
|
||||
|
||||
if (!IsEqualGUID(&src_format, format))
|
||||
if (!IsEqualGUID(&src_format, format) && !(is_1bpp_format(&src_format) && is_1bpp_format(format)))
|
||||
{
|
||||
/* FIXME: should use WICConvertBitmapSource to convert */
|
||||
ERR("format %s unsupported\n", debugstr_guid(&src_format));
|
||||
return E_FAIL;
|
||||
FIXME("format %s unsupported\n", debugstr_guid(&src_format));
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
if (xres == 0.0 || yres == 0.0)
|
||||
|
|
|
@ -95,7 +95,7 @@ static HRESULT WINAPI mqr_GetMetadataByName(IWICMetadataQueryReader *iface,
|
|||
{
|
||||
QueryReader *This = impl_from_IWICMetadataQueryReader(iface);
|
||||
FIXME("(%p,%s,%p)\n", This, wine_dbgstr_w(wzName), pvarValue);
|
||||
return E_NOTIMPL;
|
||||
return WINCODEC_ERR_PROPERTYNOTFOUND;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI mqr_GetEnumerator(IWICMetadataQueryReader *iface,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright 2009 Vincent Povirk for CodeWeavers
|
||||
* Copyright 2012 Dmitry Timoshkov
|
||||
* Copyright 2012,2016 Dmitry Timoshkov
|
||||
* Copyright 2016 Sebastian Lackner
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -431,11 +432,279 @@ static HRESULT WINAPI PaletteImpl_InitializeCustom(IWICPalette *iface,
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PaletteImpl_InitializeFromBitmap(IWICPalette *iface,
|
||||
IWICBitmapSource *pISurface, UINT colorCount, BOOL fAddTransparentColor)
|
||||
#define R_COUNT (1 << 5)
|
||||
#define R_SHIFT (8 - 5)
|
||||
#define R_SCALE 2
|
||||
|
||||
#define G_COUNT (1 << 6)
|
||||
#define G_SHIFT (8 - 6)
|
||||
#define G_SCALE 3
|
||||
|
||||
#define B_COUNT (1 << 5)
|
||||
#define B_SHIFT (8 - 5)
|
||||
#define B_SCALE 1
|
||||
|
||||
struct histogram
|
||||
{
|
||||
FIXME("(%p,%p,%u,%i): stub\n", iface, pISurface, colorCount, fAddTransparentColor);
|
||||
return E_NOTIMPL;
|
||||
unsigned int data[R_COUNT][G_COUNT][B_COUNT];
|
||||
};
|
||||
|
||||
struct box
|
||||
{
|
||||
int r_min, r_max;
|
||||
int g_min, g_max;
|
||||
int b_min, b_max;
|
||||
unsigned int count;
|
||||
unsigned int score;
|
||||
};
|
||||
|
||||
/* count nonzero elements in the histogram range [r_min, r_max] x [g_min, g_max] x [b_min, b_max] */
|
||||
static inline unsigned int histogram_count(struct histogram *h, int r_min, int r_max,
|
||||
int g_min, int g_max, int b_min, int b_max)
|
||||
{
|
||||
unsigned int count = 0;
|
||||
int r, g, b;
|
||||
for (r = r_min; r <= r_max; r++)
|
||||
for (g = g_min; g <= g_max; g++)
|
||||
for (b = b_min; b <= b_max; b++)
|
||||
if (h->data[r][g][b] != 0) count++;
|
||||
return count;
|
||||
}
|
||||
|
||||
/* compute weighted average color in the range [r_min, r_max] x [g_min, g_max] x [b_min, b_max] */
|
||||
static unsigned int histogram_color(struct histogram *h, int r_min, int r_max,
|
||||
int g_min, int g_max, int b_min, int b_max)
|
||||
{
|
||||
unsigned long long r_sum = 0, g_sum = 0, b_sum = 0;
|
||||
unsigned int tmp, count = 0;
|
||||
int r, g, b;
|
||||
|
||||
for (r = r_min; r <= r_max; r++)
|
||||
for (g = g_min; g <= g_max; g++)
|
||||
for (b = b_min; b <= b_max; b++)
|
||||
{
|
||||
if (!(tmp = h->data[r][g][b])) continue;
|
||||
r_sum += ((r << R_SHIFT) + ((1 << R_SHIFT) / 2)) * tmp;
|
||||
g_sum += ((g << G_SHIFT) + ((1 << G_SHIFT) / 2)) * tmp;
|
||||
b_sum += ((b << B_SHIFT) + ((1 << B_SHIFT) / 2)) * tmp;
|
||||
count += tmp;
|
||||
}
|
||||
|
||||
return ((b_sum + (count / 2)) / count) |
|
||||
((g_sum + (count / 2)) / count) << 8 |
|
||||
((r_sum + (count / 2)) / count) << 16 | 0xff000000;
|
||||
}
|
||||
|
||||
/* same as histogram_count */
|
||||
static inline unsigned int box_count(struct histogram *h, struct box *b)
|
||||
{
|
||||
return histogram_count(h, b->r_min, b->r_max, b->g_min, b->g_max, b->b_min, b->b_max);
|
||||
}
|
||||
|
||||
/* same as histogram_color */
|
||||
static inline unsigned int box_color(struct histogram *h, struct box *b)
|
||||
{
|
||||
return histogram_color(h, b->r_min, b->r_max, b->g_min, b->g_max, b->b_min, b->b_max);
|
||||
}
|
||||
|
||||
/* compute score used to determine best split (also called "volume") */
|
||||
static inline unsigned int box_score(struct box *b)
|
||||
{
|
||||
unsigned int tmp, sum = 0;
|
||||
tmp = ((b->r_max - b->r_min) << R_SHIFT) * R_SCALE; sum += tmp * tmp;
|
||||
tmp = ((b->g_max - b->g_min) << G_SHIFT) * G_SCALE; sum += tmp * tmp;
|
||||
tmp = ((b->b_max - b->b_min) << B_SHIFT) * B_SCALE; sum += tmp * tmp;
|
||||
return sum;
|
||||
}
|
||||
|
||||
/* attempt to shrink a box */
|
||||
static void shrink_box(struct histogram *h, struct box *b)
|
||||
{
|
||||
int i;
|
||||
for (i = b->r_min; i <= b->r_max; i++)
|
||||
if (histogram_count(h, i, i, b->g_min, b->g_max, b->b_min, b->b_max)) { b->r_min = i; break; }
|
||||
for (i = b->r_max; i >= b->r_min; i--)
|
||||
if (histogram_count(h, i, i, b->g_min, b->g_max, b->b_min, b->b_max)) { b->r_max = i; break; }
|
||||
for (i = b->g_min; i <= b->g_max; i++)
|
||||
if (histogram_count(h, b->r_min, b->r_max, i, i, b->b_min, b->b_max)) { b->g_min = i; break; }
|
||||
for (i = b->g_max; i >= b->g_min; i--)
|
||||
if (histogram_count(h, b->r_min, b->r_max, i, i, b->b_min, b->b_max)) { b->g_max = i; break; }
|
||||
for (i = b->b_min; i <= b->b_max; i++)
|
||||
if (histogram_count(h, b->r_min, b->r_max, b->g_min, b->g_max, i, i)) { b->b_min = i; break; }
|
||||
for (i = b->b_max; i >= b->b_min; i--)
|
||||
if (histogram_count(h, b->r_min, b->r_max, b->g_min, b->g_max, i, i)) { b->b_max = i; break; }
|
||||
b->count = box_count(h, b);
|
||||
b->score = box_score(b);
|
||||
}
|
||||
|
||||
/* helper for split_box */
|
||||
static inline void set_avg(int *min, int *max)
|
||||
{
|
||||
int avg = (*min + *max) / 2;
|
||||
*min = avg + 1;
|
||||
*max = avg;
|
||||
}
|
||||
|
||||
/* split a box based on the best axis */
|
||||
static void split_box(struct histogram *h, struct box *b1, struct box *b2)
|
||||
{
|
||||
int r = ((b1->r_max - b1->r_min) << R_SHIFT) * R_SCALE;
|
||||
int g = ((b1->g_max - b1->g_min) << G_SHIFT) * G_SCALE;
|
||||
int b = ((b1->b_max - b1->b_min) << B_SHIFT) * B_SCALE;
|
||||
|
||||
*b2 = *b1;
|
||||
|
||||
if (r > g)
|
||||
{
|
||||
if (b > r) set_avg(&b1->b_min, &b2->b_max);
|
||||
else set_avg(&b1->r_min, &b2->r_max);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (b > g) set_avg(&b1->b_min, &b2->b_max);
|
||||
else set_avg(&b1->g_min, &b2->g_max);
|
||||
}
|
||||
|
||||
shrink_box(h, b1);
|
||||
shrink_box(h, b2);
|
||||
}
|
||||
|
||||
/* find box suitable for split based on count */
|
||||
static struct box *find_box_max_count(struct box *b, int count)
|
||||
{
|
||||
struct box *best = NULL;
|
||||
for (; count--; b++)
|
||||
if (b->score && (!best || b->count > best->count)) best = b;
|
||||
return best;
|
||||
}
|
||||
|
||||
/* find box suitable for split based on score */
|
||||
static struct box *find_box_max_score(struct box *b, int count)
|
||||
{
|
||||
struct box *best = NULL;
|
||||
for (; count--; b++)
|
||||
if (b->score && (!best || b->score > best->score)) best = b;
|
||||
return best;
|
||||
}
|
||||
|
||||
/* compute color map with at most 'desired' colors
|
||||
* image must be in 24bpp BGR format and colors are returned in 0xAARRGGBB format */
|
||||
static int median_cut(unsigned char *image, unsigned int width, unsigned int height,
|
||||
unsigned int stride, int desired, unsigned int *colors)
|
||||
{
|
||||
struct box boxes[256];
|
||||
struct histogram *h;
|
||||
unsigned int x, y;
|
||||
unsigned char *p;
|
||||
struct box *b1, *b2;
|
||||
int numboxes, i;
|
||||
|
||||
if (!(h = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*h))))
|
||||
return 0;
|
||||
|
||||
for (y = 0; y < height; y++)
|
||||
for (x = 0, p = image + y * stride; x < width; x++, p += 3)
|
||||
h->data[p[2] >> R_SHIFT][p[1] >> G_SHIFT][p[0] >> B_SHIFT]++;
|
||||
|
||||
numboxes = 1;
|
||||
boxes[0].r_min = 0; boxes[0].r_max = R_COUNT - 1;
|
||||
boxes[0].g_min = 0; boxes[0].g_max = G_COUNT - 1;
|
||||
boxes[0].b_min = 0; boxes[0].b_max = B_COUNT - 1;
|
||||
shrink_box(h, &boxes[0]);
|
||||
|
||||
while (numboxes <= desired / 2)
|
||||
{
|
||||
if (!(b1 = find_box_max_count(boxes, numboxes))) break;
|
||||
b2 = &boxes[numboxes++];
|
||||
split_box(h, b1, b2);
|
||||
}
|
||||
while (numboxes < desired)
|
||||
{
|
||||
if (!(b1 = find_box_max_score(boxes, numboxes))) break;
|
||||
b2 = &boxes[numboxes++];
|
||||
split_box(h, b1, b2);
|
||||
}
|
||||
|
||||
for (i = 0; i < numboxes; i++)
|
||||
colors[i] = box_color(h, &boxes[i]);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, h);
|
||||
return numboxes;
|
||||
}
|
||||
|
||||
|
||||
static HRESULT WINAPI PaletteImpl_InitializeFromBitmap(IWICPalette *palette,
|
||||
IWICBitmapSource *source, UINT desired, BOOL add_transparent)
|
||||
{
|
||||
IWICImagingFactory *factory = NULL;
|
||||
IWICBitmap *rgb24_bitmap = NULL;
|
||||
IWICBitmapSource *rgb24_source;
|
||||
IWICBitmapLock *lock = NULL;
|
||||
WICPixelFormatGUID format;
|
||||
HRESULT hr;
|
||||
UINT width, height, stride, size, actual_number_of_colors;
|
||||
BYTE *src;
|
||||
WICColor colors[256];
|
||||
|
||||
TRACE("(%p,%p,%u,%d)\n", palette, source, desired, add_transparent);
|
||||
|
||||
if (!source || desired < 2 || desired > 256)
|
||||
return E_INVALIDARG;
|
||||
|
||||
hr = IWICBitmapSource_GetPixelFormat(source, &format);
|
||||
if (hr != S_OK) return hr;
|
||||
|
||||
/* For interoperability with gdiplus where PixelFormat24bppRGB actully stored
|
||||
* as BGR (and there is no a corresponding RGB format) we have to use 24bppBGR
|
||||
* to avoid format conversions.
|
||||
*/
|
||||
if (!IsEqualGUID(&format, &GUID_WICPixelFormat24bppBGR))
|
||||
{
|
||||
hr = WICConvertBitmapSource(&GUID_WICPixelFormat24bppBGR, source, &rgb24_source);
|
||||
if (hr != S_OK) return hr;
|
||||
}
|
||||
else
|
||||
rgb24_source = source;
|
||||
|
||||
hr = ComponentFactory_CreateInstance(&IID_IWICImagingFactory, (void **)&factory);
|
||||
if (hr != S_OK) goto fail;
|
||||
|
||||
hr = IWICImagingFactory_CreateBitmapFromSource(factory, rgb24_source, WICBitmapCacheOnLoad, &rgb24_bitmap);
|
||||
if (hr != S_OK) goto fail;
|
||||
|
||||
hr = IWICBitmap_Lock(rgb24_bitmap, NULL, WICBitmapLockRead, &lock);
|
||||
if (hr != S_OK) goto fail;
|
||||
|
||||
IWICBitmapLock_GetSize(lock, &width, &height);
|
||||
IWICBitmapLock_GetStride(lock, &stride);
|
||||
IWICBitmapLock_GetDataPointer(lock, &size, &src);
|
||||
|
||||
actual_number_of_colors = median_cut(src, width, height, stride, add_transparent ? desired - 1 : desired, colors);
|
||||
TRACE("actual number of colors: %u\n", actual_number_of_colors);
|
||||
|
||||
if (actual_number_of_colors)
|
||||
{
|
||||
if (add_transparent) colors[actual_number_of_colors++] = 0;
|
||||
|
||||
hr = IWICPalette_InitializeCustom(palette, colors, actual_number_of_colors);
|
||||
}
|
||||
else
|
||||
hr = E_OUTOFMEMORY;
|
||||
|
||||
fail:
|
||||
if (lock)
|
||||
IWICBitmapLock_Release(lock);
|
||||
|
||||
if (rgb24_bitmap)
|
||||
IWICBitmap_Release(rgb24_bitmap);
|
||||
|
||||
if (factory)
|
||||
IWICImagingFactory_Release(factory);
|
||||
|
||||
if (rgb24_source != source)
|
||||
IWICBitmapSource_Release(rgb24_source);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PaletteImpl_InitializeFromPalette(IWICPalette *iface,
|
||||
|
|
|
@ -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
|
||||
|
@ -18,6 +19,8 @@
|
|||
|
||||
#include "wincodecs_private.h"
|
||||
|
||||
#include <winerror.h>
|
||||
|
||||
#ifdef HAVE_PNG_H
|
||||
#include <png.h>
|
||||
#endif
|
||||
|
@ -304,18 +307,15 @@ MAKE_FUNCPTR(png_get_tRNS);
|
|||
MAKE_FUNCPTR(png_set_bgr);
|
||||
MAKE_FUNCPTR(png_set_crc_action);
|
||||
MAKE_FUNCPTR(png_set_error_fn);
|
||||
#ifdef HAVE_PNG_SET_EXPAND_GRAY_1_2_4_TO_8
|
||||
MAKE_FUNCPTR(png_set_expand_gray_1_2_4_to_8);
|
||||
#else
|
||||
MAKE_FUNCPTR(png_set_gray_1_2_4_to_8);
|
||||
#endif
|
||||
MAKE_FUNCPTR(png_set_filler);
|
||||
MAKE_FUNCPTR(png_set_gray_to_rgb);
|
||||
MAKE_FUNCPTR(png_set_interlace_handling);
|
||||
MAKE_FUNCPTR(png_set_IHDR);
|
||||
MAKE_FUNCPTR(png_set_pHYs);
|
||||
MAKE_FUNCPTR(png_set_PLTE);
|
||||
MAKE_FUNCPTR(png_set_read_fn);
|
||||
MAKE_FUNCPTR(png_set_strip_16);
|
||||
MAKE_FUNCPTR(png_set_tRNS);
|
||||
MAKE_FUNCPTR(png_set_tRNS_to_alpha);
|
||||
MAKE_FUNCPTR(png_set_write_fn);
|
||||
MAKE_FUNCPTR(png_read_end);
|
||||
|
@ -369,18 +369,15 @@ static void *load_libpng(void)
|
|||
LOAD_FUNCPTR(png_set_bgr);
|
||||
LOAD_FUNCPTR(png_set_crc_action);
|
||||
LOAD_FUNCPTR(png_set_error_fn);
|
||||
#ifdef HAVE_PNG_SET_EXPAND_GRAY_1_2_4_TO_8
|
||||
LOAD_FUNCPTR(png_set_expand_gray_1_2_4_to_8);
|
||||
#else
|
||||
LOAD_FUNCPTR(png_set_gray_1_2_4_to_8);
|
||||
#endif
|
||||
LOAD_FUNCPTR(png_set_filler);
|
||||
LOAD_FUNCPTR(png_set_gray_to_rgb);
|
||||
LOAD_FUNCPTR(png_set_interlace_handling);
|
||||
LOAD_FUNCPTR(png_set_IHDR);
|
||||
LOAD_FUNCPTR(png_set_pHYs);
|
||||
LOAD_FUNCPTR(png_set_PLTE);
|
||||
LOAD_FUNCPTR(png_set_read_fn);
|
||||
LOAD_FUNCPTR(png_set_strip_16);
|
||||
LOAD_FUNCPTR(png_set_tRNS);
|
||||
LOAD_FUNCPTR(png_set_tRNS_to_alpha);
|
||||
LOAD_FUNCPTR(png_set_write_fn);
|
||||
LOAD_FUNCPTR(png_read_end);
|
||||
|
@ -565,6 +562,8 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
|
|||
int num_trans;
|
||||
png_uint_32 transparency;
|
||||
png_color_16p trans_values;
|
||||
png_colorp png_palette;
|
||||
int num_palette;
|
||||
jmp_buf jmpbuf;
|
||||
BYTE chunk_type[4];
|
||||
ULONG chunk_size;
|
||||
|
@ -607,7 +606,7 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
|
|||
ppng_destroy_read_struct(&This->png_ptr, &This->info_ptr, &This->end_info);
|
||||
HeapFree(GetProcessHeap(), 0, row_pointers);
|
||||
This->png_ptr = NULL;
|
||||
hr = E_FAIL;
|
||||
hr = WINCODEC_ERR_UNKNOWNIMAGEFORMAT;
|
||||
goto end;
|
||||
}
|
||||
ppng_set_error_fn(This->png_ptr, jmpbuf, user_error_fn, user_warning_fn);
|
||||
|
@ -631,25 +630,11 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
|
|||
/* check for color-keyed alpha */
|
||||
transparency = ppng_get_tRNS(This->png_ptr, This->info_ptr, &trans, &num_trans, &trans_values);
|
||||
|
||||
if (transparency && color_type != PNG_COLOR_TYPE_PALETTE)
|
||||
{
|
||||
/* expand to RGBA */
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY)
|
||||
{
|
||||
if (bit_depth < 8)
|
||||
{
|
||||
#ifdef HAVE_PNG_SET_EXPAND_GRAY_1_2_4_TO_8
|
||||
ppng_set_expand_gray_1_2_4_to_8(This->png_ptr);
|
||||
#else
|
||||
ppng_set_gray_1_2_4_to_8(This->png_ptr);
|
||||
#endif
|
||||
bit_depth = 8;
|
||||
}
|
||||
ppng_set_gray_to_rgb(This->png_ptr);
|
||||
}
|
||||
ppng_set_tRNS_to_alpha(This->png_ptr);
|
||||
color_type = PNG_COLOR_TYPE_RGB_ALPHA;
|
||||
}
|
||||
if (!ppng_get_PLTE(This->png_ptr, This->info_ptr, &png_palette, &num_palette))
|
||||
num_palette = 0;
|
||||
|
||||
TRACE("color_type %d, bit_depth %d, transparency %d, num_palette %d\n",
|
||||
color_type, bit_depth, transparency, num_palette);
|
||||
|
||||
switch (color_type)
|
||||
{
|
||||
|
@ -657,14 +642,22 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
|
|||
This->bpp = bit_depth;
|
||||
switch (bit_depth)
|
||||
{
|
||||
case 1: This->format = &GUID_WICPixelFormatBlackWhite; break;
|
||||
case 2: This->format = &GUID_WICPixelFormat2bppGray; break;
|
||||
case 4: This->format = &GUID_WICPixelFormat4bppGray; break;
|
||||
case 8: This->format = &GUID_WICPixelFormat8bppGray; break;
|
||||
case 1:
|
||||
This->format = num_palette ? &GUID_WICPixelFormat1bppIndexed : &GUID_WICPixelFormatBlackWhite;
|
||||
break;
|
||||
case 2:
|
||||
This->format = num_palette ? &GUID_WICPixelFormat2bppIndexed : &GUID_WICPixelFormat2bppGray;
|
||||
break;
|
||||
case 4:
|
||||
This->format = num_palette ? &GUID_WICPixelFormat4bppIndexed : &GUID_WICPixelFormat4bppGray;
|
||||
break;
|
||||
case 8:
|
||||
This->format = num_palette ? &GUID_WICPixelFormat8bppIndexed : &GUID_WICPixelFormat8bppGray;
|
||||
break;
|
||||
case 16: This->format = &GUID_WICPixelFormat16bppGray; break;
|
||||
default:
|
||||
ERR("invalid grayscale bit depth: %i\n", bit_depth);
|
||||
hr = E_FAIL;
|
||||
hr = WINCODEC_ERR_UNKNOWNIMAGEFORMAT;
|
||||
goto end;
|
||||
}
|
||||
break;
|
||||
|
@ -838,17 +831,21 @@ static HRESULT WINAPI PngDecoder_GetDecoderInfo(IWICBitmapDecoder *iface,
|
|||
}
|
||||
|
||||
static HRESULT WINAPI PngDecoder_CopyPalette(IWICBitmapDecoder *iface,
|
||||
IWICPalette *pIPalette)
|
||||
IWICPalette *palette)
|
||||
{
|
||||
FIXME("(%p,%p): stub\n", iface, pIPalette);
|
||||
return E_NOTIMPL;
|
||||
TRACE("(%p,%p)\n", iface, palette);
|
||||
return WINCODEC_ERR_PALETTEUNAVAILABLE;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PngDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface,
|
||||
IWICMetadataQueryReader **ppIMetadataQueryReader)
|
||||
IWICMetadataQueryReader **reader)
|
||||
{
|
||||
FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryReader);
|
||||
return E_NOTIMPL;
|
||||
FIXME("(%p,%p): stub\n", iface, reader);
|
||||
|
||||
if (!reader) return E_INVALIDARG;
|
||||
|
||||
*reader = NULL;
|
||||
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PngDecoder_GetPreview(IWICBitmapDecoder *iface,
|
||||
|
@ -1318,6 +1315,10 @@ static const struct png_pixelformat formats[] = {
|
|||
{&GUID_WICPixelFormat32bppBGRA, 32, 8, PNG_COLOR_TYPE_RGB_ALPHA, 0, 1},
|
||||
{&GUID_WICPixelFormat48bppRGB, 48, 16, PNG_COLOR_TYPE_RGB, 0, 0},
|
||||
{&GUID_WICPixelFormat64bppRGBA, 64, 16, PNG_COLOR_TYPE_RGB_ALPHA, 0, 0},
|
||||
{&GUID_WICPixelFormat1bppIndexed, 1, 1, PNG_COLOR_TYPE_PALETTE, 0, 0},
|
||||
{&GUID_WICPixelFormat2bppIndexed, 2, 2, PNG_COLOR_TYPE_PALETTE, 0, 0},
|
||||
{&GUID_WICPixelFormat4bppIndexed, 4, 4, PNG_COLOR_TYPE_PALETTE, 0, 0},
|
||||
{&GUID_WICPixelFormat8bppIndexed, 8, 8, PNG_COLOR_TYPE_PALETTE, 0, 0},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
|
@ -1342,6 +1343,8 @@ typedef struct PngEncoder {
|
|||
BYTE *data;
|
||||
UINT stride;
|
||||
UINT passes;
|
||||
WICColor palette[256];
|
||||
UINT colors;
|
||||
} PngEncoder;
|
||||
|
||||
static inline PngEncoder *impl_from_IWICBitmapEncoder(IWICBitmapEncoder *iface)
|
||||
|
@ -1519,10 +1522,24 @@ static HRESULT WINAPI PngFrameEncode_SetColorContexts(IWICBitmapFrameEncode *ifa
|
|||
}
|
||||
|
||||
static HRESULT WINAPI PngFrameEncode_SetPalette(IWICBitmapFrameEncode *iface,
|
||||
IWICPalette *pIPalette)
|
||||
IWICPalette *palette)
|
||||
{
|
||||
FIXME("(%p,%p): stub\n", iface, pIPalette);
|
||||
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
|
||||
PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface);
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p)\n", iface, palette);
|
||||
|
||||
if (!palette) return E_INVALIDARG;
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
if (This->frame_initialized)
|
||||
hr = IWICPalette_GetColors(palette, 256, This->palette, &This->colors);
|
||||
else
|
||||
hr = WINCODEC_ERR_NOTINITIALIZED;
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PngFrameEncode_SetThumbnail(IWICBitmapFrameEncode *iface,
|
||||
|
@ -1589,6 +1606,42 @@ static HRESULT WINAPI PngFrameEncode_WritePixels(IWICBitmapFrameEncode *iface,
|
|||
(This->yres+0.0127) / 0.0254, PNG_RESOLUTION_METER);
|
||||
}
|
||||
|
||||
if (This->format->color_type == PNG_COLOR_TYPE_PALETTE && This->colors)
|
||||
{
|
||||
png_color png_palette[256];
|
||||
png_byte trans[256];
|
||||
UINT i, num_trans = 0, colors;
|
||||
|
||||
/* Newer libpng versions don't accept larger palettes than the declared
|
||||
* bit depth, so we need to generate the palette of the correct length.
|
||||
*/
|
||||
colors = 1 << This->format->bit_depth;
|
||||
|
||||
for (i = 0; i < colors; i++)
|
||||
{
|
||||
if (i < This->colors)
|
||||
{
|
||||
png_palette[i].red = (This->palette[i] >> 16) & 0xff;
|
||||
png_palette[i].green = (This->palette[i] >> 8) & 0xff;
|
||||
png_palette[i].blue = This->palette[i] & 0xff;
|
||||
trans[i] = (This->palette[i] >> 24) & 0xff;
|
||||
if (trans[i] != 0xff)
|
||||
num_trans++;
|
||||
}
|
||||
else
|
||||
{
|
||||
png_palette[i].red = 0;
|
||||
png_palette[i].green = 0;
|
||||
png_palette[i].blue = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ppng_set_PLTE(This->png_ptr, This->info_ptr, png_palette, colors);
|
||||
|
||||
if (num_trans)
|
||||
ppng_set_tRNS(This->png_ptr, This->info_ptr, trans, colors, NULL);
|
||||
}
|
||||
|
||||
ppng_write_info(This->png_ptr, This->info_ptr);
|
||||
|
||||
if (This->format->remove_filler)
|
||||
|
@ -1872,11 +1925,22 @@ static HRESULT WINAPI PngEncoder_GetContainerFormat(IWICBitmapEncoder *iface,
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PngEncoder_GetEncoderInfo(IWICBitmapEncoder *iface,
|
||||
IWICBitmapEncoderInfo **ppIEncoderInfo)
|
||||
static HRESULT WINAPI PngEncoder_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_WICPngEncoder, &comp_info);
|
||||
if (hr == S_OK)
|
||||
{
|
||||
hr = IWICComponentInfo_QueryInterface(comp_info, &IID_IWICBitmapEncoderInfo, (void **)info);
|
||||
IWICComponentInfo_Release(comp_info);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PngEncoder_SetColorContexts(IWICBitmapEncoder *iface,
|
||||
|
@ -1886,10 +1950,20 @@ static HRESULT WINAPI PngEncoder_SetColorContexts(IWICBitmapEncoder *iface,
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PngEncoder_SetPalette(IWICBitmapEncoder *iface, IWICPalette *pIPalette)
|
||||
static HRESULT WINAPI PngEncoder_SetPalette(IWICBitmapEncoder *iface, IWICPalette *palette)
|
||||
{
|
||||
TRACE("(%p,%p)\n", iface, pIPalette);
|
||||
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
|
||||
PngEncoder *This = impl_from_IWICBitmapEncoder(iface);
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p)\n", iface, palette);
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
hr = This->stream ? WINCODEC_ERR_UNSUPPORTEDOPERATION : WINCODEC_ERR_NOTINITIALIZED;
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PngEncoder_SetThumbnail(IWICBitmapEncoder *iface, IWICBitmapSource *pIThumbnail)
|
||||
|
@ -2027,6 +2101,7 @@ HRESULT PngEncoder_CreateInstance(REFIID iid, void** ppv)
|
|||
This->frame_committed = FALSE;
|
||||
This->committed = FALSE;
|
||||
This->data = NULL;
|
||||
This->colors = 0;
|
||||
InitializeCriticalSection(&This->lock);
|
||||
This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PngEncoder.lock");
|
||||
|
||||
|
|
|
@ -1194,6 +1194,8 @@ static GUID const * const tiff_decode_formats[] = {
|
|||
&GUID_WICPixelFormatBlackWhite,
|
||||
&GUID_WICPixelFormat4bppGray,
|
||||
&GUID_WICPixelFormat8bppGray,
|
||||
&GUID_WICPixelFormat1bppIndexed,
|
||||
&GUID_WICPixelFormat2bppIndexed,
|
||||
&GUID_WICPixelFormat4bppIndexed,
|
||||
&GUID_WICPixelFormat8bppIndexed,
|
||||
&GUID_WICPixelFormat24bppBGR,
|
||||
|
@ -1328,6 +1330,11 @@ static GUID const * const bmp_encode_formats[] = {
|
|||
&GUID_WICPixelFormat16bppBGR565,
|
||||
&GUID_WICPixelFormat24bppBGR,
|
||||
&GUID_WICPixelFormat32bppBGR,
|
||||
&GUID_WICPixelFormatBlackWhite,
|
||||
&GUID_WICPixelFormat1bppIndexed,
|
||||
&GUID_WICPixelFormat2bppIndexed,
|
||||
&GUID_WICPixelFormat4bppIndexed,
|
||||
&GUID_WICPixelFormat8bppIndexed,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -1342,6 +1349,10 @@ static GUID const * const png_encode_formats[] = {
|
|||
&GUID_WICPixelFormat32bppBGRA,
|
||||
&GUID_WICPixelFormat48bppRGB,
|
||||
&GUID_WICPixelFormat64bppRGBA,
|
||||
&GUID_WICPixelFormat1bppIndexed,
|
||||
&GUID_WICPixelFormat2bppIndexed,
|
||||
&GUID_WICPixelFormat4bppIndexed,
|
||||
&GUID_WICPixelFormat8bppIndexed,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -1349,6 +1360,10 @@ static GUID const * const tiff_encode_formats[] = {
|
|||
&GUID_WICPixelFormatBlackWhite,
|
||||
&GUID_WICPixelFormat4bppGray,
|
||||
&GUID_WICPixelFormat8bppGray,
|
||||
&GUID_WICPixelFormat1bppIndexed,
|
||||
&GUID_WICPixelFormat2bppIndexed,
|
||||
&GUID_WICPixelFormat4bppIndexed,
|
||||
&GUID_WICPixelFormat8bppIndexed,
|
||||
&GUID_WICPixelFormat24bppBGR,
|
||||
&GUID_WICPixelFormat32bppBGRA,
|
||||
&GUID_WICPixelFormat32bppPBGRA,
|
||||
|
@ -1374,6 +1389,16 @@ static struct regsvr_encoder const encoder_list[] = {
|
|||
".bmp,.dib,.rle",
|
||||
bmp_encode_formats
|
||||
},
|
||||
{ &CLSID_WICGifEncoder,
|
||||
"The Wine Project",
|
||||
"GIF Encoder",
|
||||
"1.0.0.0",
|
||||
&GUID_VendorMicrosoft,
|
||||
&GUID_ContainerFormatGif,
|
||||
"image/gif",
|
||||
".gif",
|
||||
gif_formats
|
||||
},
|
||||
{ &CLSID_WICJpegEncoder,
|
||||
"The Wine Project",
|
||||
"JPEG Encoder",
|
||||
|
@ -1706,6 +1731,8 @@ static BYTE const channel_mask_16bit2[] = { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
|
|||
static BYTE const channel_mask_16bit3[] = { 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 };
|
||||
static BYTE const channel_mask_16bit4[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff };
|
||||
|
||||
static BYTE const channel_mask_32bit[] = { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
static BYTE const channel_mask_5bit[] = { 0x1f, 0x00 };
|
||||
static BYTE const channel_mask_5bit2[] = { 0xe0, 0x03 };
|
||||
static BYTE const channel_mask_5bit3[] = { 0x00, 0x7c };
|
||||
|
@ -1722,6 +1749,8 @@ static BYTE const * const channel_masks_8bit[] = { channel_mask_8bit,
|
|||
static BYTE const * const channel_masks_16bit[] = { channel_mask_16bit,
|
||||
channel_mask_16bit2, channel_mask_16bit3, channel_mask_16bit4};
|
||||
|
||||
static BYTE const * const channel_masks_32bit[] = { channel_mask_32bit };
|
||||
|
||||
static BYTE const * const channel_masks_BGRA5551[] = { channel_mask_5bit,
|
||||
channel_mask_5bit2, channel_mask_5bit3, channel_mask_5bit4 };
|
||||
|
||||
|
@ -1916,6 +1945,17 @@ static struct regsvr_pixelformat const pixelformat_list[] = {
|
|||
WICPixelFormatNumericRepresentationUnsignedInteger,
|
||||
1
|
||||
},
|
||||
{ &GUID_WICPixelFormat32bppGrayFloat,
|
||||
"The Wine Project",
|
||||
"32bpp GrayFloat",
|
||||
NULL, /* no version */
|
||||
&GUID_VendorMicrosoft,
|
||||
32, /* bitsperpixel */
|
||||
1, /* channel count */
|
||||
channel_masks_32bit,
|
||||
WICPixelFormatNumericRepresentationFloat,
|
||||
1
|
||||
},
|
||||
{ &GUID_WICPixelFormat48bppRGB,
|
||||
"The Wine Project",
|
||||
"48bpp RGB",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright 2010 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
|
||||
|
@ -446,6 +447,12 @@ static HRESULT tiff_get_decode_info(TIFF *tiff, tiff_decode_info *decode_info)
|
|||
decode_info->bpp = bps;
|
||||
switch (bps)
|
||||
{
|
||||
case 1:
|
||||
decode_info->format = &GUID_WICPixelFormat1bppIndexed;
|
||||
break;
|
||||
case 2:
|
||||
decode_info->format = &GUID_WICPixelFormat2bppIndexed;
|
||||
break;
|
||||
case 4:
|
||||
decode_info->format = &GUID_WICPixelFormat4bppIndexed;
|
||||
break;
|
||||
|
@ -611,7 +618,7 @@ static HRESULT WINAPI TiffDecoder_Initialize(IWICBitmapDecoder *iface, IStream *
|
|||
TIFF *tiff;
|
||||
HRESULT hr=S_OK;
|
||||
|
||||
TRACE("(%p,%p,%x): stub\n", iface, pIStream, cacheOptions);
|
||||
TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions);
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
|
@ -668,17 +675,21 @@ static HRESULT WINAPI TiffDecoder_GetDecoderInfo(IWICBitmapDecoder *iface,
|
|||
}
|
||||
|
||||
static HRESULT WINAPI TiffDecoder_CopyPalette(IWICBitmapDecoder *iface,
|
||||
IWICPalette *pIPalette)
|
||||
IWICPalette *palette)
|
||||
{
|
||||
FIXME("(%p,%p): stub\n", iface, pIPalette);
|
||||
return E_NOTIMPL;
|
||||
TRACE("(%p,%p)\n", iface, palette);
|
||||
return WINCODEC_ERR_PALETTEUNAVAILABLE;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI TiffDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface,
|
||||
IWICMetadataQueryReader **ppIMetadataQueryReader)
|
||||
{
|
||||
FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryReader);
|
||||
return E_NOTIMPL;
|
||||
TRACE("(%p,%p)\n", iface, ppIMetadataQueryReader);
|
||||
|
||||
if (!ppIMetadataQueryReader) return E_INVALIDARG;
|
||||
|
||||
*ppIMetadataQueryReader = NULL;
|
||||
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI TiffDecoder_GetPreview(IWICBitmapDecoder *iface,
|
||||
|
@ -1080,7 +1091,7 @@ static HRESULT WINAPI TiffFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface,
|
|||
if (cbStride < bytesperrow)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if ((cbStride * prc->Height) > cbBufferSize)
|
||||
if ((cbStride * (prc->Height-1)) + ((prc->Width * This->decode_info.bpp) + 7)/8 > cbBufferSize)
|
||||
return E_INVALIDARG;
|
||||
|
||||
min_tile_x = prc->X / This->decode_info.tile_width;
|
||||
|
@ -1394,6 +1405,10 @@ static const struct tiff_encode_format formats[] = {
|
|||
{&GUID_WICPixelFormat48bppRGB, 2, 16, 3, 48, 0, 0, 0},
|
||||
{&GUID_WICPixelFormat64bppRGBA, 2, 16, 4, 64, 1, 2, 0},
|
||||
{&GUID_WICPixelFormat64bppPRGBA, 2, 16, 4, 64, 1, 1, 0},
|
||||
{&GUID_WICPixelFormat1bppIndexed, 3, 1, 1, 1, 0, 0, 0},
|
||||
{&GUID_WICPixelFormat2bppIndexed, 3, 2, 1, 2, 0, 0, 0},
|
||||
{&GUID_WICPixelFormat4bppIndexed, 3, 4, 1, 4, 0, 0, 0},
|
||||
{&GUID_WICPixelFormat8bppIndexed, 3, 8, 1, 8, 0, 0, 0},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
@ -1426,6 +1441,8 @@ typedef struct TiffFrameEncode {
|
|||
UINT width, height;
|
||||
double xres, yres;
|
||||
UINT lines_written;
|
||||
WICColor palette[256];
|
||||
UINT colors;
|
||||
} TiffFrameEncode;
|
||||
|
||||
static inline TiffFrameEncode *impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEncode *iface)
|
||||
|
@ -1587,10 +1604,24 @@ static HRESULT WINAPI TiffFrameEncode_SetColorContexts(IWICBitmapFrameEncode *if
|
|||
}
|
||||
|
||||
static HRESULT WINAPI TiffFrameEncode_SetPalette(IWICBitmapFrameEncode *iface,
|
||||
IWICPalette *pIPalette)
|
||||
IWICPalette *palette)
|
||||
{
|
||||
FIXME("(%p,%p): stub\n", iface, pIPalette);
|
||||
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
|
||||
TiffFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p)\n", iface, palette);
|
||||
|
||||
if (!palette) return E_INVALIDARG;
|
||||
|
||||
EnterCriticalSection(&This->parent->lock);
|
||||
|
||||
if (This->initialized)
|
||||
hr = IWICPalette_GetColors(palette, 256, This->palette, &This->colors);
|
||||
else
|
||||
hr = WINCODEC_ERR_NOTINITIALIZED;
|
||||
|
||||
LeaveCriticalSection(&This->parent->lock);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI TiffFrameEncode_SetThumbnail(IWICBitmapFrameEncode *iface,
|
||||
|
@ -1660,6 +1691,21 @@ static HRESULT WINAPI TiffFrameEncode_WritePixels(IWICBitmapFrameEncode *iface,
|
|||
pTIFFSetField(This->parent->tiff, TIFFTAG_YRESOLUTION, (float)This->yres);
|
||||
}
|
||||
|
||||
if (This->format->bpp <= 8 && This->colors && !IsEqualGUID(This->format->guid, &GUID_WICPixelFormatBlackWhite))
|
||||
{
|
||||
uint16 red[256], green[256], blue[256];
|
||||
UINT i;
|
||||
|
||||
for (i = 0; i < This->colors; i++)
|
||||
{
|
||||
red[i] = (This->palette[i] >> 0) & 0xff00;
|
||||
green[i] = This->palette[i] & 0xff00;
|
||||
blue[i] = (This->palette[i] << 8) & 0xff00;
|
||||
}
|
||||
|
||||
pTIFFSetField(This->parent->tiff, TIFFTAG_COLORMAP, red, green, blue);
|
||||
}
|
||||
|
||||
This->info_written = TRUE;
|
||||
}
|
||||
|
||||
|
@ -1858,11 +1904,22 @@ static HRESULT WINAPI TiffEncoder_GetContainerFormat(IWICBitmapEncoder *iface,
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI TiffEncoder_GetEncoderInfo(IWICBitmapEncoder *iface,
|
||||
IWICBitmapEncoderInfo **ppIEncoderInfo)
|
||||
static HRESULT WINAPI TiffEncoder_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_WICTiffEncoder, &comp_info);
|
||||
if (hr == S_OK)
|
||||
{
|
||||
hr = IWICComponentInfo_QueryInterface(comp_info, &IID_IWICBitmapEncoderInfo, (void **)info);
|
||||
IWICComponentInfo_Release(comp_info);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI TiffEncoder_SetColorContexts(IWICBitmapEncoder *iface,
|
||||
|
@ -1872,10 +1929,20 @@ static HRESULT WINAPI TiffEncoder_SetColorContexts(IWICBitmapEncoder *iface,
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI TiffEncoder_SetPalette(IWICBitmapEncoder *iface, IWICPalette *pIPalette)
|
||||
static HRESULT WINAPI TiffEncoder_SetPalette(IWICBitmapEncoder *iface, IWICPalette *palette)
|
||||
{
|
||||
TRACE("(%p,%p)\n", iface, pIPalette);
|
||||
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
|
||||
TiffEncoder *This = impl_from_IWICBitmapEncoder(iface);
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p)\n", iface, palette);
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
hr = This->stream ? WINCODEC_ERR_UNSUPPORTEDOPERATION : WINCODEC_ERR_NOTINITIALIZED;
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI TiffEncoder_SetThumbnail(IWICBitmapEncoder *iface, IWICBitmapSource *pIThumbnail)
|
||||
|
@ -1912,7 +1979,7 @@ static HRESULT WINAPI TiffEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
|
|||
hr = E_FAIL;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
if (SUCCEEDED(hr) && ppIEncoderOptions)
|
||||
{
|
||||
PROPBAG2 opts[2]= {{0}};
|
||||
opts[0].pstrName = (LPOLESTR)wszTiffCompressionMethod;
|
||||
|
@ -1930,7 +1997,7 @@ static HRESULT WINAPI TiffEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
|
|||
VARIANT v;
|
||||
VariantInit(&v);
|
||||
V_VT(&v) = VT_UI1;
|
||||
V_UNION(&v, bVal) = WICTiffCompressionDontCare;
|
||||
V_UI1(&v) = WICTiffCompressionDontCare;
|
||||
hr = IPropertyBag2_Write(*ppIEncoderOptions, 1, opts, &v);
|
||||
VariantClear(&v);
|
||||
if (FAILED(hr))
|
||||
|
@ -1959,6 +2026,7 @@ static HRESULT WINAPI TiffEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
|
|||
result->xres = 0.0;
|
||||
result->yres = 0.0;
|
||||
result->lines_written = 0;
|
||||
result->colors = 0;
|
||||
|
||||
IWICBitmapEncoder_AddRef(iface);
|
||||
*ppIFrameEncode = &result->IWICBitmapFrameEncode_iface;
|
||||
|
@ -1971,7 +2039,7 @@ static HRESULT WINAPI TiffEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
|
|||
else
|
||||
hr = E_OUTOFMEMORY;
|
||||
|
||||
if (FAILED(hr))
|
||||
if (FAILED(hr) && ppIEncoderOptions)
|
||||
{
|
||||
IPropertyBag2_Release(*ppIEncoderOptions);
|
||||
*ppIEncoderOptions = NULL;
|
||||
|
|
|
@ -76,7 +76,8 @@ typedef void (__cdecl typeof(png_write_info))(struct png_struct_def *, struct pn
|
|||
typedef void (__cdecl typeof(png_write_rows))(struct png_struct_def *, unsigned char **row, unsigned int);
|
||||
typedef unsigned int (__cdecl typeof(png_get_iCCP))(struct png_struct_def *, struct png_info_def *, char **, int *, char **, unsigned int *);
|
||||
typedef void (__cdecl typeof(png_set_crc_action))(struct png_struct_def *, int, int);
|
||||
|
||||
typedef void (__stdcall typeof(png_set_PLTE))(struct png_struct_def *, struct png_info_def *, const struct png_color_struct *, int);
|
||||
typedef void (__stdcall typeof(png_set_tRNS))(struct png_struct_def *, struct png_info_def *, const unsigned char *, int, const struct png_color_16_struct *);
|
||||
typedef void *thandle_t_1;
|
||||
typedef int (*TIFFReadWriteProc_1)(thandle_t_1, void *, long);
|
||||
typedef unsigned int (*TIFFSeekProc_1)(void *, unsigned int, int);
|
||||
|
|
|
@ -169,6 +169,7 @@ extern HRESULT PngEncoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN
|
|||
extern HRESULT BmpEncoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN;
|
||||
extern HRESULT DibDecoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN;
|
||||
extern HRESULT GifDecoder_CreateInstance(REFIID riid, void** ppv) DECLSPEC_HIDDEN;
|
||||
extern HRESULT GifEncoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN;
|
||||
extern HRESULT IcoDecoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN;
|
||||
extern HRESULT JpegDecoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN;
|
||||
extern HRESULT JpegEncoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -69,6 +69,13 @@ coclass WICBmpEncoder { interface IWICBitmapEncoder; }
|
|||
]
|
||||
coclass WICGifDecoder { interface IWICBitmapDecoder; }
|
||||
|
||||
[
|
||||
helpstring("WIC GIF Encoder"),
|
||||
threading(both),
|
||||
uuid(114f5598-0b22-40a0-86a1-c83ea495adbd)
|
||||
]
|
||||
coclass WICGifEncoder { interface IWICBitmapEncoder; }
|
||||
|
||||
[
|
||||
helpstring("WIC ICO Decoder"),
|
||||
threading(both),
|
||||
|
|
|
@ -196,7 +196,7 @@ reactos/dll/win32/version # Synced to WineStaging-1.9.11
|
|||
reactos/dll/win32/vssapi # Synced to WineStaging-1.9.11
|
||||
reactos/dll/win32/wbemdisp # Synced to WineStaging-1.9.16
|
||||
reactos/dll/win32/wbemprox # Synced to WineStaging-1.9.23
|
||||
reactos/dll/win32/windowscodecs # Synced to WineStaging-1.9.16
|
||||
reactos/dll/win32/windowscodecs # Synced to WineStaging-1.9.23
|
||||
reactos/dll/win32/windowscodecsext # Synced to WineStaging-1.9.11
|
||||
reactos/dll/win32/winemp3.acm # Synced to WineStaging-1.9.11
|
||||
reactos/dll/win32/wing32 # Synced to WineStaging-1.9.11
|
||||
|
|
Loading…
Reference in a new issue