static HRESULT WINAPI PngDecoder_Frame_CopyPalette(IWICBitmapFrameDecode *iface, IWICPalette *pIPalette) { PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface); png_uint_32 ret; png_colorp png_palette; int num_palette; WICColor palette[256]; png_bytep trans; int num_trans; png_color_16p trans_values; int i; HRESULT hr=S_OK; TRACE("(%p,%p)\n", iface, pIPalette); EnterCriticalSection(&This->lock); ret = ppng_get_PLTE(This->png_ptr, This->info_ptr, &png_palette, &num_palette); if (!ret) { hr = WINCODEC_ERR_PALETTEUNAVAILABLE; goto end; } if (num_palette > 256) { ERR("palette has %i colors?!\n", num_palette); hr = E_FAIL; goto end; } for (i=0; i<num_palette; i++) { palette[i] = (0xff000000| png_palette[i].red << 16| png_palette[i].green << 8| png_palette[i].blue); } ret = ppng_get_tRNS(This->png_ptr, This->info_ptr, &trans, &num_trans, &trans_values); if (ret) { for (i=0; i<num_trans; i++) { palette[trans[i]] = 0x00000000; } } end: LeaveCriticalSection(&This->lock); if (SUCCEEDED(hr)) hr = IWICPalette_InitializeCustom(pIPalette, palette, num_palette); return hr; }
static HRESULT WINAPI PngDecoder_Frame_CopyPalette(IWICBitmapFrameDecode *iface, IWICPalette *pIPalette) { PngDecoder *This = impl_from_frame(iface); png_uint_32 ret; png_colorp png_palette; int num_palette; WICColor palette[256]; png_bytep trans; int num_trans; png_color_16p trans_values; int i; TRACE("(%p,%p)\n", iface, pIPalette); ret = ppng_get_PLTE(This->png_ptr, This->info_ptr, &png_palette, &num_palette); if (!ret) return WINCODEC_ERR_PALETTEUNAVAILABLE; if (num_palette > 256) { ERR("palette has %i colors?!\n", num_palette); return E_FAIL; } for (i=0; i<num_palette; i++) { palette[i] = (0xff000000| png_palette[i].red << 16| png_palette[i].green << 8| png_palette[i].blue); } ret = ppng_get_tRNS(This->png_ptr, This->info_ptr, &trans, &num_trans, &trans_values); if (ret) { for (i=0; i<num_trans; i++) { palette[trans[i]] = 0x00000000; } } return IWICPalette_InitializeCustom(pIPalette, palette, num_palette); }
static HRESULT WINAPI GifFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface, IWICPalette *pIPalette) { GifFrameDecode *This = (GifFrameDecode*)iface; WICColor colors[256]; ColorMapObject *cm = This->frame->ImageDesc.ColorMap; int i, trans; ExtensionBlock *eb; TRACE("(%p,%p)\n", iface, pIPalette); if (!cm) cm = This->parent->gif->SColorMap; if (cm->ColorCount > 256) { ERR("GIF contains %i colors???\n", cm->ColorCount); return E_FAIL; } for (i = 0; i < cm->ColorCount; i++) { colors[i] = 0xff000000| /* alpha */ cm->Colors[i].Red << 16| cm->Colors[i].Green << 8| cm->Colors[i].Blue; } /* look for the transparent color extension */ for (i = 0; i < This->frame->ExtensionBlockCount; ++i) { eb = This->frame->ExtensionBlocks + i; if (eb->Function == 0xF9 && eb->ByteCount == 4) { if ((eb->Bytes[0] & 1) == 1) { trans = (unsigned char)eb->Bytes[3]; colors[trans] &= 0xffffff; /* set alpha to 0 */ break; } } } IWICPalette_InitializeCustom(pIPalette, colors, cm->ColorCount); return S_OK; }
HRESULT WINAPI IWICPalette_InitializeCustom_Proxy_W(IWICPalette *iface, WICColor *pColors, UINT colorCount) { return IWICPalette_InitializeCustom(iface, pColors, colorCount); }
static HRESULT WINAPI ComponentFactory_CreateBitmapFromHBITMAP(IWICComponentFactory *iface, HBITMAP hbm, HPALETTE hpal, WICBitmapAlphaChannelOption option, IWICBitmap **bitmap) { BITMAP bm; HRESULT hr; WICPixelFormatGUID format; IWICBitmapLock *lock; UINT size, num_palette_entries = 0; PALETTEENTRY entry[256]; TRACE("(%p,%p,%p,%u,%p)\n", iface, hbm, hpal, option, bitmap); if (!bitmap) return E_INVALIDARG; if (GetObjectW(hbm, sizeof(bm), &bm) != sizeof(bm)) return WINCODEC_ERR_WIN32ERROR; if (hpal) { num_palette_entries = GetPaletteEntries(hpal, 0, 256, entry); if (!num_palette_entries) return WINCODEC_ERR_WIN32ERROR; } /* TODO: Figure out the correct format for 16, 32, 64 bpp */ switch(bm.bmBitsPixel) { case 1: format = GUID_WICPixelFormat1bppIndexed; break; case 4: format = GUID_WICPixelFormat4bppIndexed; break; case 8: format = GUID_WICPixelFormat8bppIndexed; break; case 16: if (!get_16bpp_format(hbm, &format)) return E_INVALIDARG; break; case 24: format = GUID_WICPixelFormat24bppBGR; break; case 32: switch (option) { case WICBitmapUseAlpha: format = GUID_WICPixelFormat32bppBGRA; break; case WICBitmapUsePremultipliedAlpha: format = GUID_WICPixelFormat32bppPBGRA; break; case WICBitmapIgnoreAlpha: format = GUID_WICPixelFormat32bppBGR; break; default: return E_INVALIDARG; } break; case 48: format = GUID_WICPixelFormat48bppRGB; break; default: FIXME("unsupported %d bpp\n", bm.bmBitsPixel); return E_INVALIDARG; } hr = BitmapImpl_Create(bm.bmWidth, bm.bmHeight, bm.bmWidthBytes, 0, NULL, &format, option, bitmap); if (hr != S_OK) return hr; hr = IWICBitmap_Lock(*bitmap, NULL, WICBitmapLockWrite, &lock); if (hr == S_OK) { BYTE *buffer; HDC hdc; char bmibuf[FIELD_OFFSET(BITMAPINFO, bmiColors[256])]; BITMAPINFO *bmi = (BITMAPINFO *)bmibuf; IWICBitmapLock_GetDataPointer(lock, &size, &buffer); hdc = CreateCompatibleDC(0); bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi->bmiHeader.biBitCount = 0; GetDIBits(hdc, hbm, 0, 0, NULL, bmi, DIB_RGB_COLORS); bmi->bmiHeader.biHeight = -bm.bmHeight; GetDIBits(hdc, hbm, 0, bm.bmHeight, buffer, bmi, DIB_RGB_COLORS); DeleteDC(hdc); IWICBitmapLock_Release(lock); if (num_palette_entries) { IWICPalette *palette; WICColor colors[256]; UINT i; hr = PaletteImpl_Create(&palette); if (hr == S_OK) { for (i = 0; i < num_palette_entries; i++) colors[i] = 0xff000000 | entry[i].peRed << 16 | entry[i].peGreen << 8 | entry[i].peBlue; hr = IWICPalette_InitializeCustom(palette, colors, num_palette_entries); if (hr == S_OK) hr = IWICBitmap_SetPalette(*bitmap, palette); IWICPalette_Release(palette); } } } if (hr != S_OK) { IWICBitmap_Release(*bitmap); *bitmap = NULL; } return hr; }
static void test_custom_palette(void) { IWICImagingFactory *factory; IWICPalette *palette, *palette2; HRESULT hr; WICBitmapPaletteType type=0xffffffff; UINT count=1; const WICColor initcolors[4]={0xff000000,0xff0000ff,0xffffff00,0xffffffff}; WICColor colors[4]; BOOL boolresult; hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory); ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); if (FAILED(hr)) return; hr = IWICImagingFactory_CreatePalette(factory, &palette); ok(SUCCEEDED(hr), "CreatePalette failed, hr=%x\n", hr); if (SUCCEEDED(hr)) { hr = IWICPalette_GetType(palette, &type); ok(SUCCEEDED(hr), "GetType failed, hr=%x\n", hr); ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %x\n", type); hr = IWICPalette_GetColorCount(palette, &count); ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr); ok(count == 0, "expected 0, got %u\n", count); hr = IWICPalette_GetColors(palette, 0, colors, &count); ok(SUCCEEDED(hr), "GetColors failed, hr=%x\n", hr); ok(count == 0, "expected 0, got %u\n", count); hr = IWICPalette_GetColors(palette, 4, colors, &count); ok(SUCCEEDED(hr), "GetColors failed, hr=%x\n", hr); ok(count == 0, "expected 0, got %u\n", count); memcpy(colors, initcolors, sizeof(initcolors)); hr = IWICPalette_InitializeCustom(palette, colors, 4); ok(SUCCEEDED(hr), "InitializeCustom failed, hr=%x\n", hr); hr = IWICPalette_GetType(palette, &type); ok(SUCCEEDED(hr), "GetType failed, hr=%x\n", hr); ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %x\n", type); hr = IWICPalette_GetColorCount(palette, &count); ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr); ok(count == 4, "expected 4, got %u\n", count); memset(colors, 0, sizeof(colors)); count = 0; hr = IWICPalette_GetColors(palette, 4, colors, &count); ok(SUCCEEDED(hr), "GetColors failed, hr=%x\n", hr); ok(count == 4, "expected 4, got %u\n", count); ok(!memcmp(colors, initcolors, sizeof(colors)), "got unexpected palette data\n"); memset(colors, 0, sizeof(colors)); count = 0; hr = IWICPalette_GetColors(palette, 2, colors, &count); ok(SUCCEEDED(hr), "GetColors failed, hr=%x\n", hr); ok(count == 2, "expected 2, got %u\n", count); ok(!memcmp(colors, initcolors, sizeof(WICColor)*2), "got unexpected palette data\n"); count = 0; hr = IWICPalette_GetColors(palette, 6, colors, &count); ok(SUCCEEDED(hr), "GetColors failed, hr=%x\n", hr); ok(count == 4, "expected 4, got %u\n", count); hr = IWICPalette_HasAlpha(palette, &boolresult); ok(SUCCEEDED(hr), "HasAlpha failed, hr=%x\n", hr); ok(!boolresult, "expected FALSE, got TRUE\n"); hr = IWICPalette_IsBlackWhite(palette, &boolresult); ok(SUCCEEDED(hr), "IsBlackWhite failed, hr=%x\n", hr); ok(!boolresult, "expected FALSE, got TRUE\n"); hr = IWICPalette_IsGrayscale(palette, &boolresult); ok(SUCCEEDED(hr), "IsGrayscale failed, hr=%x\n", hr); ok(!boolresult, "expected FALSE, got TRUE\n"); hr = IWICImagingFactory_CreatePalette(factory, &palette2); ok(SUCCEEDED(hr), "CreatePalette failed, hr=%x\n", hr); hr = IWICPalette_InitializeFromPalette(palette2, palette); ok(SUCCEEDED(hr), "InitializeFromPalette failed, hr=%x\n", hr); type = 0xdeadbeef; hr = IWICPalette_GetType(palette2, &type); ok(SUCCEEDED(hr), "GetType failed, hr=%x\n", hr); ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %x\n", type); count = 0xdeadbeef; hr = IWICPalette_GetColorCount(palette2, &count); ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr); ok(count == 4, "expected 4, got %u\n", count); memset(colors, 0, sizeof(colors)); count = 0xdeadbeef; hr = IWICPalette_GetColors(palette2, 4, colors, &count); ok(SUCCEEDED(hr), "GetColors failed, hr=%x\n", hr); ok(count == 4, "expected 4, got %u\n", count); ok(!memcmp(colors, initcolors, sizeof(colors)), "got unexpected palette data\n"); /* try a palette with some alpha in it */ colors[2] = 0x80ffffff; hr = IWICPalette_InitializeCustom(palette, colors, 4); ok(SUCCEEDED(hr), "InitializeCustom failed, hr=%x\n", hr); hr = IWICPalette_HasAlpha(palette, &boolresult); ok(SUCCEEDED(hr), "HasAlpha failed, hr=%x\n", hr); ok(boolresult, "expected TRUE, got FALSE\n"); /* setting to a 0-color palette is acceptable */ hr = IWICPalette_InitializeCustom(palette, NULL, 0); ok(SUCCEEDED(hr), "InitializeCustom failed, hr=%x\n", hr); type = 0xdeadbeef; hr = IWICPalette_GetType(palette, &type); ok(SUCCEEDED(hr), "GetType failed, hr=%x\n", hr); ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %x\n", type); count = 0xdeadbeef; hr = IWICPalette_GetColorCount(palette, &count); ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr); ok(count == 0, "expected 0, got %u\n", count); count = 0xdeadbeef; hr = IWICPalette_GetColors(palette, 4, colors, &count); ok(SUCCEEDED(hr), "GetColors failed, hr=%x\n", hr); ok(count == 0, "expected 0, got %u\n", count); hr = IWICPalette_InitializeFromPalette(palette2, palette); ok(SUCCEEDED(hr), "InitializeFromPalette failed, hr=%x\n", hr); type = 0xdeadbeef; hr = IWICPalette_GetType(palette2, &type); ok(SUCCEEDED(hr), "GetType failed, hr=%x\n", hr); ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %x\n", type); count = 0xdeadbeef; hr = IWICPalette_GetColorCount(palette2, &count); ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr); ok(count == 0, "expected 0, got %u\n", count); memset(colors, 0, sizeof(colors)); count = 0xdeadbeef; hr = IWICPalette_GetColors(palette2, 4, colors, &count); ok(SUCCEEDED(hr), "GetColors failed, hr=%x\n", hr); ok(count == 0, "expected 0, got %u\n", count); /* IWICPalette is paranoid about NULL pointers */ hr = IWICPalette_GetType(palette, NULL); ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); hr = IWICPalette_GetColorCount(palette, NULL); ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); hr = IWICPalette_InitializeCustom(palette, NULL, 4); ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); hr = IWICPalette_GetColors(palette, 4, NULL, &count); ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); hr = IWICPalette_GetColors(palette, 4, colors, NULL); ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); hr = IWICPalette_HasAlpha(palette, NULL); ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); hr = IWICPalette_IsBlackWhite(palette, NULL); ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); hr = IWICPalette_IsGrayscale(palette, NULL); ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); hr = IWICPalette_InitializeFromPalette(palette, NULL); ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); IWICPalette_Release(palette2); IWICPalette_Release(palette); } IWICImagingFactory_Release(factory); }
static HRESULT WINAPI BmpFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface, IWICPalette *pIPalette) { HRESULT hr; BmpFrameDecode *This = (BmpFrameDecode*)iface; int count; WICColor *wiccolors=NULL; RGBTRIPLE *bgrcolors=NULL; TRACE("(%p,%p)\n", iface, pIPalette); if (This->bih.bV5Size == sizeof(BITMAPCOREHEADER)) { BITMAPCOREHEADER *bch = (BITMAPCOREHEADER*)&This->bih; if (bch->bcBitCount <= 8) { /* 2**n colors in BGR format after the header */ ULONG tablesize, bytesread; LARGE_INTEGER offset; int i; count = 1 << bch->bcBitCount; wiccolors = HeapAlloc(GetProcessHeap(), 0, sizeof(WICColor) * count); tablesize = sizeof(RGBTRIPLE) * count; bgrcolors = HeapAlloc(GetProcessHeap(), 0, tablesize); if (!wiccolors || !bgrcolors) { hr = E_OUTOFMEMORY; goto end; } offset.QuadPart = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPCOREHEADER); hr = IStream_Seek(This->stream, offset, STREAM_SEEK_SET, NULL); if (FAILED(hr)) goto end; hr = IStream_Read(This->stream, bgrcolors, tablesize, &bytesread); if (FAILED(hr)) goto end; if (bytesread != tablesize) { hr = E_FAIL; goto end; } for (i=0; i<count; i++) { wiccolors[i] = 0xff000000| (bgrcolors[i].rgbtRed<<16)| (bgrcolors[i].rgbtGreen<<8)| bgrcolors[i].rgbtBlue; } } else { return WINCODEC_ERR_PALETTEUNAVAILABLE; } } else { if (This->bih.bV5BitCount <= 8) { ULONG tablesize, bytesread; LARGE_INTEGER offset; int i; if (This->bih.bV5ClrUsed == 0) count = 1 << This->bih.bV5BitCount; else count = This->bih.bV5ClrUsed; tablesize = sizeof(WICColor) * count; wiccolors = HeapAlloc(GetProcessHeap(), 0, tablesize); if (!wiccolors) return E_OUTOFMEMORY; offset.QuadPart = sizeof(BITMAPFILEHEADER) + This->bih.bV5Size; hr = IStream_Seek(This->stream, offset, STREAM_SEEK_SET, NULL); if (FAILED(hr)) goto end; hr = IStream_Read(This->stream, wiccolors, tablesize, &bytesread); if (FAILED(hr)) goto end; if (bytesread != tablesize) { hr = E_FAIL; goto end; } /* convert from BGR to BGRA by setting alpha to 100% */ for (i=0; i<count; i++) wiccolors[i] |= 0xff000000; } else { return WINCODEC_ERR_PALETTEUNAVAILABLE; } } hr = IWICPalette_InitializeCustom(pIPalette, wiccolors, count); end: HeapFree(GetProcessHeap(), 0, wiccolors); HeapFree(GetProcessHeap(), 0, bgrcolors); return hr; }