Skip to content

Commit

Permalink
windowscodecs: Add conversions from PixelFormat32bppBGRA->PixelFormat…
Browse files Browse the repository at this point in the history
…16bppBGRA5551.

(cherry picked from commit dcb5c97)
  • Loading branch information
Czahrien authored and ivyl committed Sep 4, 2024
1 parent 337204d commit 488fb29
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 1 deletion.
65 changes: 64 additions & 1 deletion dlls/windowscodecs/converter.c
Original file line number Diff line number Diff line change
Expand Up @@ -1492,6 +1492,69 @@ static HRESULT copypixels_to_8bppIndexed(struct FormatConverter *This, const WIC
return hr;
}

static HRESULT copypixels_to_16bppBGRA5551(struct FormatConverter *This, const WICRect *prc,
UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
{
switch (source_format)
{
case format_16bppBGRA5551:
if (prc)
return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
return S_OK;
case format_32bppBGRA:
if(prc)
{
HRESULT res;
INT x, y;
BYTE *srcdata;
UINT srcstride, srcdatasize;
const BYTE *srcrow;
const DWORD *srcpixel;
BYTE *dstrow;
DWORD srcval = 0;
WORD *dstpixel;

int a, r, g, b;

srcstride = 4 * prc->Width;
srcdatasize = srcstride * prc->Height;

srcdata = malloc(srcdatasize);
if (!srcdata) return E_OUTOFMEMORY;

res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata);
if(SUCCEEDED(res))
{
srcrow = srcdata;
dstrow = pbBuffer;
for(y=0; y< prc->Height; y++) {
srcpixel = (const DWORD*)srcrow;
dstpixel = (WORD *)dstrow;
for(x=0; x<prc->Width; x++) {
srcval=*srcpixel++;
a = (srcval & 0xff000000) >> 24;
r = (srcval & 0x00ff0000) >> 16;
g = (srcval & 0x0000ff00) >> 8;
b = (srcval & 0x000000ff);
a = (a >> 7) << 15;
r = (r >> 3) << 10;
g = (g >> 3) << 5;
b = (b >> 3);
*dstpixel++ = (a|r|g|b);
}
srcrow += srcstride;
dstrow += cbStride;
}
}
free(srcdata);
}
return S_OK;
default:
FIXME("Unimplemented conversion path! %d\n", source_format);
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}
}

static const struct pixelformatinfo supported_formats[] = {
{format_1bppIndexed, &GUID_WICPixelFormat1bppIndexed, NULL, TRUE},
{format_2bppIndexed, &GUID_WICPixelFormat2bppIndexed, NULL, TRUE},
Expand All @@ -1504,7 +1567,7 @@ static const struct pixelformatinfo supported_formats[] = {
{format_16bppGray, &GUID_WICPixelFormat16bppGray, NULL},
{format_16bppBGR555, &GUID_WICPixelFormat16bppBGR555, NULL},
{format_16bppBGR565, &GUID_WICPixelFormat16bppBGR565, NULL},
{format_16bppBGRA5551, &GUID_WICPixelFormat16bppBGRA5551, NULL},
{format_16bppBGRA5551, &GUID_WICPixelFormat16bppBGRA5551, copypixels_to_16bppBGRA5551},
{format_24bppBGR, &GUID_WICPixelFormat24bppBGR, copypixels_to_24bppBGR},
{format_24bppRGB, &GUID_WICPixelFormat24bppRGB, copypixels_to_24bppRGB},
{format_32bppGrayFloat, &GUID_WICPixelFormat32bppGrayFloat, copypixels_to_32bppGrayFloat},
Expand Down
21 changes: 21 additions & 0 deletions dlls/windowscodecs/tests/converter.c
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,26 @@ static const BYTE bits_24bppBGR_gray[] = {
static const struct bitmap_data testdata_24bppBGR_gray = {
&GUID_WICPixelFormat24bppBGR, 24, bits_24bppBGR_gray, 32, 2, 96.0, 96.0};

#define TO_16bppBGRA5551(b,g,r,a) ( \
((a >> 7) << 15) | \
((r >> 3) << 10) | \
((g >> 3) << 5) | \
((b >> 3)) \
)

static const WORD bits_16bppBGRA5551[] = {
TO_16bppBGRA5551(255,0,0,255), TO_16bppBGRA5551(0,255,0,255), TO_16bppBGRA5551(0,0,255,255), TO_16bppBGRA5551(0,0,0,255), TO_16bppBGRA5551(255,0,0,255), TO_16bppBGRA5551(0,255,0,255), TO_16bppBGRA5551(0,0,255,255), TO_16bppBGRA5551(0,0,0,255),
TO_16bppBGRA5551(255,0,0,255), TO_16bppBGRA5551(0,255,0,255), TO_16bppBGRA5551(0,0,255,255), TO_16bppBGRA5551(0,0,0,255), TO_16bppBGRA5551(255,0,0,255), TO_16bppBGRA5551(0,255,0,255), TO_16bppBGRA5551(0,0,255,255), TO_16bppBGRA5551(0,0,0,255),
TO_16bppBGRA5551(255,0,0,255), TO_16bppBGRA5551(0,255,0,255), TO_16bppBGRA5551(0,0,255,255), TO_16bppBGRA5551(0,0,0,255), TO_16bppBGRA5551(255,0,0,255), TO_16bppBGRA5551(0,255,0,255), TO_16bppBGRA5551(0,0,255,255), TO_16bppBGRA5551(0,0,0,255),
TO_16bppBGRA5551(255,0,0,255), TO_16bppBGRA5551(0,255,0,255), TO_16bppBGRA5551(0,0,255,255), TO_16bppBGRA5551(0,0,0,255), TO_16bppBGRA5551(255,0,0,255), TO_16bppBGRA5551(0,255,0,255), TO_16bppBGRA5551(0,0,255,255), TO_16bppBGRA5551(0,0,0,255),
TO_16bppBGRA5551(0,255,255,255), TO_16bppBGRA5551(255,0,255,255), TO_16bppBGRA5551(255,255,0,255), TO_16bppBGRA5551(255,255,255,255), TO_16bppBGRA5551(0,255,255,255), TO_16bppBGRA5551(255,0,255,255), TO_16bppBGRA5551(255,255,0,255), TO_16bppBGRA5551(255,255,255,255),
TO_16bppBGRA5551(0,255,255,255), TO_16bppBGRA5551(255,0,255,255), TO_16bppBGRA5551(255,255,0,255), TO_16bppBGRA5551(255,255,255,255), TO_16bppBGRA5551(0,255,255,255), TO_16bppBGRA5551(255,0,255,255), TO_16bppBGRA5551(255,255,0,255), TO_16bppBGRA5551(255,255,255,255),
TO_16bppBGRA5551(0,255,255,255), TO_16bppBGRA5551(255,0,255,255), TO_16bppBGRA5551(255,255,0,255), TO_16bppBGRA5551(255,255,255,255), TO_16bppBGRA5551(0,255,255,255), TO_16bppBGRA5551(255,0,255,255), TO_16bppBGRA5551(255,255,0,255), TO_16bppBGRA5551(255,255,255,255),
TO_16bppBGRA5551(0,255,255,255), TO_16bppBGRA5551(255,0,255,255), TO_16bppBGRA5551(255,255,0,255), TO_16bppBGRA5551(255,255,255,255), TO_16bppBGRA5551(0,255,255,255), TO_16bppBGRA5551(255,0,255,255), TO_16bppBGRA5551(255,255,0,255), TO_16bppBGRA5551(255,255,255,255)};

static const struct bitmap_data testdata_16bppBGRA5551 = {
&GUID_WICPixelFormat16bppBGRA5551, 16, (BYTE*)bits_16bppBGRA5551, 32, 2, 96.0, 96.0};

static void test_conversion(const struct bitmap_data *src, const struct bitmap_data *dst, const char *name, BOOL todo)
{
BitmapTestSrc *src_obj;
Expand Down Expand Up @@ -2054,6 +2074,7 @@ START_TEST(converter)
test_conversion(&testdata_32bppBGR, &testdata_8bppGray, "32bppBGR -> 8bppGray", FALSE);
test_conversion(&testdata_32bppGrayFloat, &testdata_24bppBGR_gray, "32bppGrayFloat -> 24bppBGR gray", FALSE);
test_conversion(&testdata_32bppGrayFloat, &testdata_8bppGray, "32bppGrayFloat -> 8bppGray", FALSE);
test_conversion(&testdata_32bppBGRA, &testdata_16bppBGRA5551, "32bppBGRA -> 16bppBGRA5551", FALSE);

test_invalid_conversion();
test_default_converter();
Expand Down

0 comments on commit 488fb29

Please sign in to comment.