Commit ee3c1790 authored by Martin Petricek's avatar Martin Petricek Committed by Alexandre Julliard

gdiplus: Support for indexed formats in GdipBitmapSetPixel.

parent 85386c2c
...@@ -296,6 +296,53 @@ GpStatus WINGDIPAPI GdipBitmapGetPixel(GpBitmap* bitmap, INT x, INT y, ...@@ -296,6 +296,53 @@ GpStatus WINGDIPAPI GdipBitmapGetPixel(GpBitmap* bitmap, INT x, INT y,
return Ok; return Ok;
} }
static inline UINT get_palette_index(BYTE r, BYTE g, BYTE b, BYTE a, GpBitmap* bitmap) {
BYTE index = 0;
int best_distance = 0x7fff;
int distance;
int i;
/* This algorithm scans entire pallete,
computes difference from desired color (all color components have equal weight)
and returns the index of color with least difference.
Note: Maybe it could be replaced with a better algorithm for better image quality
and performance, though better algorithm would probably need some pre-built lookup
tables and thus may actually be slower if this method is called only few times per
every image.
*/
for(i=0;i<bitmap->image.palette_size;i++) {
ARGB color=bitmap->image.palette_entries[i];
distance=abs(b-(color & 0xff)) + abs(g-(color>>8 & 0xff)) + abs(r-(color>>16 & 0xff)) + abs(a-(color>>24 & 0xff));
if (distance<best_distance) {
best_distance=distance;
index=i;
}
}
return index;
}
static inline void setpixel_8bppIndexed(BYTE r, BYTE g, BYTE b, BYTE a,
BYTE *row, UINT x, GpBitmap* bitmap)
{
BYTE index = get_palette_index(r,g,b,a,bitmap);
row[x]=index;
}
static inline void setpixel_1bppIndexed(BYTE r, BYTE g, BYTE b, BYTE a,
BYTE *row, UINT x, GpBitmap* bitmap)
{
row[x/8] = (row[x/8] & ~(1<<(7-x%8))) | (get_palette_index(r,g,b,a,bitmap)<<(7-x%8));
}
static inline void setpixel_4bppIndexed(BYTE r, BYTE g, BYTE b, BYTE a,
BYTE *row, UINT x, GpBitmap* bitmap)
{
if (x & 1)
row[x/2] = (row[x/2] & 0xf0) | get_palette_index(r,g,b,a,bitmap);
else
row[x/2] = (row[x/2] & 0x0f) | get_palette_index(r,g,b,a,bitmap)<<4;
}
static inline void setpixel_16bppGrayScale(BYTE r, BYTE g, BYTE b, BYTE a, static inline void setpixel_16bppGrayScale(BYTE r, BYTE g, BYTE b, BYTE a,
BYTE *row, UINT x) BYTE *row, UINT x)
{ {
...@@ -434,6 +481,15 @@ GpStatus WINGDIPAPI GdipBitmapSetPixel(GpBitmap* bitmap, INT x, INT y, ...@@ -434,6 +481,15 @@ GpStatus WINGDIPAPI GdipBitmapSetPixel(GpBitmap* bitmap, INT x, INT y,
case PixelFormat64bppPARGB: case PixelFormat64bppPARGB:
setpixel_64bppPARGB(r,g,b,a,row,x); setpixel_64bppPARGB(r,g,b,a,row,x);
break; break;
case PixelFormat8bppIndexed:
setpixel_8bppIndexed(r,g,b,a,row,x,bitmap);
break;
case PixelFormat4bppIndexed:
setpixel_4bppIndexed(r,g,b,a,row,x,bitmap);
break;
case PixelFormat1bppIndexed:
setpixel_1bppIndexed(r,g,b,a,row,x,bitmap);
break;
default: default:
FIXME("not implemented for format 0x%x\n", bitmap->format); FIXME("not implemented for format 0x%x\n", bitmap->format);
return NotImplemented; return NotImplemented;
......
...@@ -1568,7 +1568,7 @@ static void test_palette(void) ...@@ -1568,7 +1568,7 @@ static void test_palette(void)
expect(0xff000000, color); expect(0xff000000, color);
stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffffffff); stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffffffff);
todo_wine ok((stat == Ok) || ok((stat == Ok) ||
broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat); broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat);
if (stat == Ok) if (stat == Ok)
...@@ -1601,7 +1601,7 @@ static void test_palette(void) ...@@ -1601,7 +1601,7 @@ static void test_palette(void)
expect(0xff000000, color); expect(0xff000000, color);
stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffff00ff); stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffff00ff);
todo_wine ok((stat == Ok) || ok((stat == Ok) ||
broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat); broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat);
if (stat == Ok) if (stat == Ok)
...@@ -1634,7 +1634,7 @@ static void test_palette(void) ...@@ -1634,7 +1634,7 @@ static void test_palette(void)
expect(0xff000000, color); expect(0xff000000, color);
stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffcccccc); stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffcccccc);
todo_wine ok((stat == Ok) || ok((stat == Ok) ||
broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat); broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat);
if (stat == Ok) if (stat == Ok)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment