From 912b02c2e3b548ffb956f4d87b9a89ca831dab02 Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Wed, 23 Sep 2009 10:41:13 -0500 Subject: [PATCH] gdiplus: Implement GdipBitmapGetPixel. --- dlls/gdiplus/image.c | 166 ++++++++++++++++++++++++++++++++++++++++++-- dlls/gdiplus/tests/image.c | 20 +++--- 2 files changed, 170 insertions(+), 16 deletions(-) diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c index 3dc41b8..dc9f954 100644 --- a/dlls/gdiplus/image.c +++ b/dlls/gdiplus/image.c @@ -94,21 +94,175 @@ GpStatus WINGDIPAPI GdipBitmapCreateApplyEffect(GpBitmap** inputBitmaps, return NotImplemented; } +static inline void getpixel_16bppGrayScale(BYTE *r, BYTE *g, BYTE *b, BYTE *a, + const BYTE *row, UINT x) +{ + *r = *g = *b = row[x*2+1]; + *a = 255; +} + +static inline void getpixel_16bppRGB555(BYTE *r, BYTE *g, BYTE *b, BYTE *a, + const BYTE *row, UINT x) +{ + WORD pixel = *((WORD*)(row)+x); + *r = (pixel>>7&0xf8)|(pixel>>12&0x7); + *g = (pixel>>2&0xf8)|(pixel>>6&0x7); + *b = (pixel<<3&0xf8)|(pixel>>2&0x7); + *a = 255; +} + +static inline void getpixel_16bppRGB565(BYTE *r, BYTE *g, BYTE *b, BYTE *a, + const BYTE *row, UINT x) +{ + WORD pixel = *((WORD*)(row)+x); + *r = (pixel>>8&0xf8)|(pixel>>13&0x7); + *g = (pixel>>3&0xfc)|(pixel>>9&0x3); + *b = (pixel<<3&0xf8)|(pixel>>2&0x7); + *a = 255; +} + +static inline void getpixel_16bppARGB1555(BYTE *r, BYTE *g, BYTE *b, BYTE *a, + const BYTE *row, UINT x) +{ + WORD pixel = *((WORD*)(row)+x); + *r = (pixel>>7&0xf8)|(pixel>>12&0x7); + *g = (pixel>>2&0xf8)|(pixel>>6&0x7); + *b = (pixel<<3&0xf8)|(pixel>>2&0x7); + if ((pixel&0x8000) == 0x8000) + *a = 255; + else + *a = 0; +} + +static inline void getpixel_24bppRGB(BYTE *r, BYTE *g, BYTE *b, BYTE *a, + const BYTE *row, UINT x) +{ + *r = row[x*3+2]; + *g = row[x*3+1]; + *b = row[x*3]; + *a = 255; +} + +static inline void getpixel_32bppRGB(BYTE *r, BYTE *g, BYTE *b, BYTE *a, + const BYTE *row, UINT x) +{ + *r = row[x*4+2]; + *g = row[x*4+1]; + *b = row[x*4]; + *a = 255; +} + +static inline void getpixel_32bppARGB(BYTE *r, BYTE *g, BYTE *b, BYTE *a, + const BYTE *row, UINT x) +{ + *r = row[x*4+2]; + *g = row[x*4+1]; + *b = row[x*4]; + *a = row[x*4+3]; +} + +static inline void getpixel_32bppPARGB(BYTE *r, BYTE *g, BYTE *b, BYTE *a, + const BYTE *row, UINT x) +{ + *a = row[x*4+3]; + if (*a == 0) + *r = *g = *b = 0; + else + { + *r = row[x*4+2] * 255 / *a; + *g = row[x*4+1] * 255 / *a; + *b = row[x*4] * 255 / *a; + } +} + +static inline void getpixel_48bppRGB(BYTE *r, BYTE *g, BYTE *b, BYTE *a, + const BYTE *row, UINT x) +{ + *r = row[x*6+5]; + *g = row[x*6+3]; + *b = row[x*6+1]; + *a = 255; +} + +static inline void getpixel_64bppARGB(BYTE *r, BYTE *g, BYTE *b, BYTE *a, + const BYTE *row, UINT x) +{ + *r = row[x*8+5]; + *g = row[x*8+3]; + *b = row[x*8+1]; + *a = row[x*8+7]; +} + +static inline void getpixel_64bppPARGB(BYTE *r, BYTE *g, BYTE *b, BYTE *a, + const BYTE *row, UINT x) +{ + *a = row[x*8+7]; + if (*a == 0) + *r = *g = *b = 0; + else + { + *r = row[x*8+5] * 255 / *a; + *g = row[x*8+3] * 255 / *a; + *b = row[x*8+1] * 255 / *a; + } +} + GpStatus WINGDIPAPI GdipBitmapGetPixel(GpBitmap* bitmap, INT x, INT y, ARGB *color) { - static int calls; + BYTE r, g, b, a; + BYTE *row; TRACE("%p %d %d %p\n", bitmap, x, y, color); - if(!bitmap || !color) + if(!bitmap || !color || + x < 0 || y < 0 || x >= bitmap->width || y >= bitmap->height) return InvalidParameter; - if(!(calls++)) - FIXME("not implemented\n"); + row = bitmap->bits+bitmap->stride*y; + + switch (bitmap->format) + { + case PixelFormat16bppGrayScale: + getpixel_16bppGrayScale(&r,&g,&b,&a,row,x); + break; + case PixelFormat16bppRGB555: + getpixel_16bppRGB555(&r,&g,&b,&a,row,x); + break; + case PixelFormat16bppRGB565: + getpixel_16bppRGB565(&r,&g,&b,&a,row,x); + break; + case PixelFormat16bppARGB1555: + getpixel_16bppARGB1555(&r,&g,&b,&a,row,x); + break; + case PixelFormat24bppRGB: + getpixel_24bppRGB(&r,&g,&b,&a,row,x); + break; + case PixelFormat32bppRGB: + getpixel_32bppRGB(&r,&g,&b,&a,row,x); + break; + case PixelFormat32bppARGB: + getpixel_32bppARGB(&r,&g,&b,&a,row,x); + break; + case PixelFormat32bppPARGB: + getpixel_32bppPARGB(&r,&g,&b,&a,row,x); + break; + case PixelFormat48bppRGB: + getpixel_48bppRGB(&r,&g,&b,&a,row,x); + break; + case PixelFormat64bppARGB: + getpixel_64bppARGB(&r,&g,&b,&a,row,x); + break; + case PixelFormat64bppPARGB: + getpixel_64bppPARGB(&r,&g,&b,&a,row,x); + break; + default: + FIXME("not implemented for format 0x%x\n", bitmap->format); + return NotImplemented; + } - *color = 0xdeadbeef; + *color = a<<24|r<<16|g<<8|b; - return NotImplemented; + return Ok; } GpStatus WINGDIPAPI GdipBitmapSetPixel(GpBitmap* bitmap, INT x, INT y, diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c index d32b9f8..3037f6c 100644 --- a/dlls/gdiplus/tests/image.c +++ b/dlls/gdiplus/tests/image.c @@ -822,37 +822,37 @@ static void test_getsetpixel(void) /* out of bounds */ stat = GdipBitmapGetPixel(bitmap, -1, 1, &color); - todo_wine expect(InvalidParameter, stat); + expect(InvalidParameter, stat); stat = GdipBitmapSetPixel(bitmap, -1, 1, 0); todo_wine expect(InvalidParameter, stat); stat = GdipBitmapGetPixel(bitmap, 1, -1, &color); - todo_wine expect(InvalidParameter, stat); + expect(InvalidParameter, stat); stat = GdipBitmapSetPixel(bitmap, 1, -1, 0); todo_wine expect(InvalidParameter, stat); stat = GdipBitmapGetPixel(bitmap, 2, 1, &color); - todo_wine expect(InvalidParameter, stat); + expect(InvalidParameter, stat); stat = GdipBitmapSetPixel(bitmap, 2, 1, 0); todo_wine expect(InvalidParameter, stat); stat = GdipBitmapGetPixel(bitmap, 1, 2, &color); - todo_wine expect(InvalidParameter, stat); + expect(InvalidParameter, stat); stat = GdipBitmapSetPixel(bitmap, 1, 2, 0); todo_wine expect(InvalidParameter, stat); /* valid use */ stat = GdipBitmapGetPixel(bitmap, 1, 1, &color); - todo_wine expect(Ok, stat); - todo_wine expect(0xffffffff, color); + expect(Ok, stat); + expect(0xffffffff, color); stat = GdipBitmapGetPixel(bitmap, 0, 1, &color); - todo_wine expect(Ok, stat); - todo_wine expect(0xff0000ff, color); + expect(Ok, stat); + expect(0xff0000ff, color); stat = GdipBitmapSetPixel(bitmap, 1, 1, 0xff676869); todo_wine expect(Ok, stat); @@ -861,11 +861,11 @@ static void test_getsetpixel(void) todo_wine expect(Ok, stat); stat = GdipBitmapGetPixel(bitmap, 1, 1, &color); - todo_wine expect(Ok, stat); + expect(Ok, stat); todo_wine expect(0xff676869, color); stat = GdipBitmapGetPixel(bitmap, 0, 0, &color); - todo_wine expect(Ok, stat); + expect(Ok, stat); todo_wine expect(0xff474849, color); stat = GdipDisposeImage((GpImage*)bitmap); -- 1.5.4.3