Vincent Povirk : gdiplus: Implement GdipImageRotateFlip.

Alexandre Julliard julliard at winehq.org
Wed Mar 31 10:04:51 CDT 2010


Module: wine
Branch: master
Commit: f2e3d996093420e2ff477c3d13902ec60be1c615
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=f2e3d996093420e2ff477c3d13902ec60be1c615

Author: Vincent Povirk <vincent at codeweavers.com>
Date:   Wed Feb 24 16:59:50 2010 -0600

gdiplus: Implement GdipImageRotateFlip.

---

 dlls/gdiplus/image.c       |  141 +++++++++++++++++++++++++++++++++++++++++++-
 dlls/gdiplus/tests/image.c |   38 ++++++------
 2 files changed, 158 insertions(+), 21 deletions(-)

diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c
index 8736b23..0a73dcf 100644
--- a/dlls/gdiplus/image.c
+++ b/dlls/gdiplus/image.c
@@ -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;
 }
diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c
index 262f9a2..0ca22e5 100644
--- a/dlls/gdiplus/tests/image.c
+++ b/dlls/gdiplus/tests/image.c
@@ -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]);




More information about the wine-cvs mailing list