Module: wine Branch: master Commit: 7fdc0208e869f315bc6ceec36553a171c3a061a6 URL: http://source.winehq.org/git/wine.git/?a=commit;h=7fdc0208e869f315bc6ceec365...
Author: Vincent Povirk vincent@codeweavers.com Date: Fri Aug 28 16:53:57 2009 -0500
gdiplus: Return the real image bits from LockBits when possible.
---
dlls/gdiplus/gdiplus_private.h | 2 ++ dlls/gdiplus/image.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 0 deletions(-)
diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index 7197463..5e615e1 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -224,6 +224,8 @@ struct GpBitmap{ BYTE *bitmapbits; /* pointer to the buffer we passed in BitmapLockBits */ HBITMAP hbitmap; HDC hdc; + BYTE *bits; /* actual image bits if this is a DIB */ + INT stride; /* stride of bits if this is a DIB */ };
struct GpCachedBitmap{ diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c index cf56b90..164ab29 100644 --- a/dlls/gdiplus/image.c +++ b/dlls/gdiplus/image.c @@ -167,6 +167,23 @@ GpStatus WINGDIPAPI GdipBitmapLockBits(GpBitmap* bitmap, GDIPCONST GpRect* rect, if(bitmap->lockmode) return WrongState;
+ if (bitmap->bits && bitmap->format == format) + { + /* no conversion is necessary; just use the bits directly */ + lockeddata->Width = act_rect.Width; + lockeddata->Height = act_rect.Height; + lockeddata->PixelFormat = format; + lockeddata->Reserved = flags; + lockeddata->Stride = bitmap->stride; + lockeddata->Scan0 = bitmap->bits + (bitspp / 8) * act_rect.X + + bitmap->stride * act_rect.Y; + + bitmap->lockmode = flags; + bitmap->numlocks++; + + return Ok; + } + hbm = bitmap->hbitmap; hdc = bitmap->hdc; bm_is_selected = (hdc != 0); @@ -263,6 +280,13 @@ GpStatus WINGDIPAPI GdipBitmapUnlockBits(GpBitmap* bitmap, return Ok; }
+ if (!bitmap->bitmapbits) + { + /* we passed a direct reference; no need to do anything */ + bitmap->lockmode = 0; + return Ok; + } + hbm = bitmap->hbitmap; hdc = bitmap->hdc; bm_is_selected = (hdc != 0); @@ -638,6 +662,7 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromHICON(HICON hicon, GpBitmap** bitmap) (*bitmap)->height = ipicture_pixel_height((*bitmap)->image.picture); (*bitmap)->hbitmap = NULL; (*bitmap)->hdc = NULL; + (*bitmap)->bits = NULL;
DeleteObject(iinfo.hbmColor); DeleteObject(iinfo.hbmMask); @@ -697,6 +722,7 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT width, INT height, INT stride, if (!hbitmap) return GenericError;
/* copy bits to the dib if necessary */ + /* FIXME: should reference the bits instead of copying them */ if (scan0) for (i=0; i<height; i++) memcpy(bits+i*dib_stride, scan0+i*stride, row_size); @@ -716,6 +742,8 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT width, INT height, INT stride, (*bitmap)->image.picture = NULL; (*bitmap)->hbitmap = hbitmap; (*bitmap)->hdc = NULL; + (*bitmap)->bits = bits; + (*bitmap)->stride = dib_stride;
return Ok; } @@ -1293,6 +1321,7 @@ static GpStatus decode_image_olepicture_bitmap(IStream* stream, REFCLSID clsid,
(*((GpBitmap**) image))->hbitmap = hbm; (*((GpBitmap**) image))->hdc = hdc; + (*((GpBitmap**) image))->bits = NULL;
bmch = (BITMAPCOREHEADER*) (&pbmi->bmiHeader); bmch->bcSize = sizeof(BITMAPCOREHEADER);