gdiplus: Implement GdipImageRotateFlip.

This commit is contained in:
Vincent Povirk 2010-02-24 16:59:50 -06:00 committed by Alexandre Julliard
parent deb6466f3f
commit f2e3d99609
2 changed files with 158 additions and 21 deletions

View File

@ -1831,6 +1831,37 @@ GpStatus WINGDIPAPI GdipEmfToWmfBits(HENHMETAFILE hemf, UINT cbData16,
return NotImplemented;
}
/* Internal utility function: Replace the image data of dst with that of src,
* and free src. */
static void move_bitmap(GpBitmap *dst, GpBitmap *src, BOOL clobber_palette)
{
GdipFree(dst->bitmapbits);
DeleteDC(dst->hdc);
DeleteObject(dst->hbitmap);
if (clobber_palette)
{
GdipFree(dst->image.palette_entries);
dst->image.palette_flags = src->image.palette_flags;
dst->image.palette_count = src->image.palette_count;
dst->image.palette_entries = src->image.palette_entries;
}
else
GdipFree(src->image.palette_entries);
dst->image.xres = src->image.xres;
dst->image.yres = src->image.yres;
dst->width = src->width;
dst->height = src->height;
dst->format = src->format;
dst->hbitmap = src->hbitmap;
dst->hdc = src->hdc;
dst->bits = src->bits;
dst->stride = src->stride;
GdipFree(src);
}
GpStatus WINGDIPAPI GdipDisposeImage(GpImage *image)
{
TRACE("%p\n", image);
@ -3438,6 +3469,112 @@ GpStatus WINGDIPAPI GdipGetImageThumbnail(GpImage *image, UINT width, UINT heigh
*/
GpStatus WINGDIPAPI GdipImageRotateFlip(GpImage *image, RotateFlipType type)
{
FIXME("(%p %u) stub\n", image, type);
return NotImplemented;
GpBitmap *new_bitmap;
GpBitmap *bitmap;
int bpp, bytesperpixel;
int rotate_90, flip_x, flip_y;
int src_x_offset, src_y_offset;
LPBYTE src_origin;
UINT x, y, width, height;
BitmapData src_lock, dst_lock;
GpStatus stat;
TRACE("(%p, %u)\n", image, type);
rotate_90 = type&1;
flip_x = (type&6) == 2 || (type&6) == 4;
flip_y = (type&3) == 1 || (type&3) == 2;
if (image->type != ImageTypeBitmap)
{
FIXME("Not implemented for type %i\n", image->type);
return NotImplemented;
}
bitmap = (GpBitmap*)image;
bpp = PIXELFORMATBPP(bitmap->format);
if (bpp < 8)
{
FIXME("Not implemented for %i bit images\n", bpp);
return NotImplemented;
}
if (rotate_90)
{
width = bitmap->height;
height = bitmap->width;
}
else
{
width = bitmap->width;
height = bitmap->height;
}
bytesperpixel = bpp/8;
stat = GdipCreateBitmapFromScan0(width, height, 0, bitmap->format, NULL, &new_bitmap);
if (stat != Ok)
return stat;
stat = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead, bitmap->format, &src_lock);
if (stat == Ok)
{
stat = GdipBitmapLockBits(new_bitmap, NULL, ImageLockModeWrite, bitmap->format, &dst_lock);
if (stat == Ok)
{
LPBYTE src_row, src_pixel;
LPBYTE dst_row, dst_pixel;
src_origin = src_lock.Scan0;
if (flip_x) src_origin += bytesperpixel * (bitmap->width - 1);
if (flip_y) src_origin += src_lock.Stride * (bitmap->height - 1);
if (rotate_90)
{
if (flip_y) src_x_offset = -src_lock.Stride;
else src_x_offset = src_lock.Stride;
if (flip_x) src_y_offset = -bytesperpixel;
else src_y_offset = bytesperpixel;
}
else
{
if (flip_x) src_x_offset = -bytesperpixel;
else src_x_offset = bytesperpixel;
if (flip_y) src_y_offset = -src_lock.Stride;
else src_y_offset = src_lock.Stride;
}
src_row = src_origin;
dst_row = dst_lock.Scan0;
for (y=0; y<height; y++)
{
src_pixel = src_row;
dst_pixel = dst_row;
for (x=0; x<width; x++)
{
/* FIXME: This could probably be faster without memcpy. */
memcpy(dst_pixel, src_pixel, bytesperpixel);
dst_pixel += bytesperpixel;
src_pixel += src_x_offset;
}
src_row += src_y_offset;
dst_row += dst_lock.Stride;
}
GdipBitmapUnlockBits(new_bitmap, &dst_lock);
}
GdipBitmapUnlockBits(bitmap, &src_lock);
}
if (stat == Ok)
move_bitmap(bitmap, new_bitmap, FALSE);
else
GdipDisposeImage((GpImage*)new_bitmap);
return stat;
}

View File

@ -1719,30 +1719,30 @@ static void test_rotateflip(void)
expect(Ok, stat);
stat = GdipImageRotateFlip(bitmap, Rotate90FlipNone);
todo_wine expect(Ok, stat);
expect(Ok, stat);
stat = GdipGetImageWidth(bitmap, &width);
expect(Ok, stat);
stat = GdipGetImageHeight(bitmap, &height);
expect(Ok, stat);
todo_wine expect(2, width);
todo_wine expect(3, height);
expect(2, width);
expect(3, height);
stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 0, &color);
expect(Ok, stat);
todo_wine expect(0xff00ffff, color);
expect(0xff00ffff, color);
stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 1, 0, &color);
expect(Ok, stat);
todo_wine expect(0xffff0000, color);
expect(0xffff0000, color);
stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 2, &color);
todo_wine expect(Ok, stat);
todo_wine expect(0xffffff00, color);
expect(Ok, stat);
expect(0xffffff00, color);
stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 1, 2, &color);
todo_wine expect(Ok, stat);
todo_wine expect(0xff0000ff, color);
expect(Ok, stat);
expect(0xff0000ff, color);
expect(0, bits[0]);
expect(0, bits[1]);
@ -1755,7 +1755,7 @@ static void test_rotateflip(void)
expect(Ok, stat);
stat = GdipImageRotateFlip(bitmap, RotateNoneFlipX);
todo_wine expect(Ok, stat);
expect(Ok, stat);
stat = GdipGetImageWidth(bitmap, &width);
expect(Ok, stat);
@ -1766,19 +1766,19 @@ static void test_rotateflip(void)
stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 0, &color);
expect(Ok, stat);
todo_wine expect(0xff0000ff, color);
expect(0xff0000ff, color);
stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 0, &color);
expect(Ok, stat);
todo_wine expect(0xffff0000, color);
expect(0xffff0000, color);
stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 1, &color);
expect(Ok, stat);
todo_wine expect(0xffffff00, color);
expect(0xffffff00, color);
stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 1, &color);
expect(Ok, stat);
todo_wine expect(0xff00ffff, color);
expect(0xff00ffff, color);
expect(0, bits[0]);
expect(0, bits[1]);
@ -1791,7 +1791,7 @@ static void test_rotateflip(void)
expect(Ok, stat);
stat = GdipImageRotateFlip(bitmap, RotateNoneFlipY);
todo_wine expect(Ok, stat);
expect(Ok, stat);
stat = GdipGetImageWidth(bitmap, &width);
expect(Ok, stat);
@ -1802,19 +1802,19 @@ static void test_rotateflip(void)
stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 0, &color);
expect(Ok, stat);
todo_wine expect(0xff00ffff, color);
expect(0xff00ffff, color);
stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 0, &color);
expect(Ok, stat);
todo_wine expect(0xffffff00, color);
expect(0xffffff00, color);
stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 1, &color);
expect(Ok, stat);
todo_wine expect(0xffff0000, color);
expect(0xffff0000, color);
stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 1, &color);
expect(Ok, stat);
todo_wine expect(0xff0000ff, color);
expect(0xff0000ff, color);
expect(0, bits[0]);
expect(0, bits[1]);