Evan Stade : gdiplus: Fixed conformance of GdipCreateBitmapFromScan0.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Aug 9 08:23:15 CDT 2007


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

Author: Evan Stade <estade at gmail.com>
Date:   Wed Aug  8 19:42:24 2007 -0700

gdiplus: Fixed conformance of GdipCreateBitmapFromScan0.

---

 dlls/gdiplus/image.c       |   29 +++++++++++++++++++++++++----
 dlls/gdiplus/tests/image.c |   30 ++++++++++++------------------
 2 files changed, 37 insertions(+), 22 deletions(-)

diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c
index ec52d5d..d34e76d 100644
--- a/dlls/gdiplus/image.c
+++ b/dlls/gdiplus/image.c
@@ -257,17 +257,34 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT width, INT height, INT stride,
     BITMAPFILEHEADER *bmfh;
     BITMAPINFOHEADER *bmih;
     BYTE *buff;
-    INT datalen = stride * height, size;
+    INT datalen, size;
     IStream *stream;
 
     TRACE("%d %d %d %d %p %p\n", width, height, stride, format, scan0, bitmap);
 
-    if(!scan0 || !bitmap)
+    if(!bitmap || width <= 0 || height <= 0 || (scan0 && (stride % 4))){
+        *bitmap = NULL;
+        return InvalidParameter;
+    }
+
+    if(scan0 && !stride)
         return InvalidParameter;
 
+    /* FIXME: windows allows negative stride (reads backwards from scan0) */
+    if(stride < 0){
+        FIXME("negative stride\n");
+        return InvalidParameter;
+    }
+
     *bitmap = GdipAlloc(sizeof(GpBitmap));
     if(!*bitmap)    return OutOfMemory;
 
+    if(stride == 0){
+        stride = width * (PIXELFORMATBPP(format) / 8);
+        stride = (stride + 3) & ~3;
+    }
+
+    datalen = abs(stride * height);
     size = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + datalen;
     buff = GdipAlloc(size);
     if(!buff){
@@ -284,12 +301,16 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT width, INT height, INT stride,
 
     bmih->biSize            = sizeof(BITMAPINFOHEADER);
     bmih->biWidth           = width;
-    bmih->biHeight          = height;
+    bmih->biHeight          = -height;
     /* FIXME: use the rest of the data from format */
     bmih->biBitCount        = PIXELFORMATBPP(format);
     bmih->biCompression     = BI_RGB;
+    bmih->biSizeImage       = datalen;
 
-    memcpy(bmih + 1, scan0, datalen);
+    if(scan0)
+        memcpy(bmih + 1, scan0, datalen);
+    else
+        memset(bmih + 1, 0, datalen);
 
     if(CreateStreamOnHGlobal(buff, TRUE, &stream) != S_OK){
         ERR("could not make stream\n");
diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c
index ac86fb7..0dda717 100644
--- a/dlls/gdiplus/tests/image.c
+++ b/dlls/gdiplus/tests/image.c
@@ -32,29 +32,27 @@ static void test_Scan0()
 
     bm = NULL;
     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB, NULL, &bm);
-    todo_wine{
-        expect(Ok, stat);
-        ok(NULL != bm, "Expected bitmap to be initialized\n");
-    }
+    expect(Ok, stat);
+    ok(NULL != bm, "Expected bitmap to be initialized\n");
     GdipDisposeImage((GpImage*)bm);
 
     bm = (GpBitmap*)0xdeadbeef;
     stat = GdipCreateBitmapFromScan0(10, -10, 10, PixelFormat24bppRGB, NULL, &bm);
     expect(InvalidParameter, stat);
-    todo_wine
-        expect(NULL, bm);
+
+    expect(NULL, bm);
 
     bm = (GpBitmap*)0xdeadbeef;
     stat = GdipCreateBitmapFromScan0(-10, 10, 10, PixelFormat24bppRGB, NULL, &bm);
     expect(InvalidParameter, stat);
-    todo_wine
-        expect(NULL, bm);
+
+    expect(NULL, bm);
 
     bm = (GpBitmap*)0xdeadbeef;
     stat = GdipCreateBitmapFromScan0(10, 0, 10, PixelFormat24bppRGB, NULL, &bm);
     expect(InvalidParameter, stat);
-    todo_wine
-        expect(NULL, bm);
+
+    expect(NULL, bm);
 
     bm = NULL;
     stat = GdipCreateBitmapFromScan0(10, 10, 12, PixelFormat24bppRGB, buff, &bm);
@@ -64,17 +62,13 @@ static void test_Scan0()
 
     bm = (GpBitmap*) 0xdeadbeef;
     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB, buff, &bm);
-    todo_wine{
-        expect(InvalidParameter, stat);
-        expect(NULL, bm);
-    }
+    expect(InvalidParameter, stat);
+    expect(NULL, bm);
 
     bm = (GpBitmap*)0xdeadbeef;
     stat = GdipCreateBitmapFromScan0(10, 10, 0, PixelFormat24bppRGB, buff, &bm);
-    todo_wine{
-        expect(InvalidParameter, stat);
-        expect(0xdeadbeef, bm);
-    }
+    expect(InvalidParameter, stat);
+    expect(0xdeadbeef, bm);
 }
 
 START_TEST(image)




More information about the wine-cvs mailing list