[WINDOWSCODECS] Sync with Wine Staging 1.9.23. CORE-12409

svn path=/trunk/; revision=73303
This commit is contained in:
Amine Khaldi 2016-11-17 23:22:42 +00:00
parent 8209287044
commit c3af8cc0b7
19 changed files with 1866 additions and 206 deletions

View file

@ -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);

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
@ -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;

View file

@ -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},

View file

@ -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

View file

@ -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);

View file

@ -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;
}
}

View file

@ -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)
{

View file

@ -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");

View file

@ -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)

View file

@ -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,

View file

@ -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,

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
@ -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");

View file

@ -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",

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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),

View file

@ -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