gdiplus: Do not create gdi32 objects for Bitmap objects.

This commit is contained in:
Esme Povirk 2024-05-02 16:17:35 -05:00 committed by Alexandre Julliard
parent 101ffccebf
commit 6b19838162
4 changed files with 44 additions and 141 deletions

View file

@ -49,6 +49,8 @@
#define GIF_DISPOSE_RESTORE_TO_BKGND 2
#define GIF_DISPOSE_RESTORE_TO_PREV 3
#define PIXELFORMATBPP(x) ((x) ? ((x) >> 8) & 255 : 24)
COLORREF ARGB2COLORREF(ARGB color);
HBITMAP ARGB2BMP(ARGB color);
@ -467,8 +469,6 @@ struct GpBitmap{
PixelFormat format;
ImageLockMode lockmode;
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 */
BYTE *own_bits; /* image bits that need to be freed with this object */

View file

@ -3402,69 +3402,44 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
else
{
HDC hdc;
BOOL temp_hdc = FALSE, temp_bitmap = FALSE;
HBITMAP hbitmap, old_hbm=NULL;
HRGN hrgn;
INT save_state;
BITMAPINFOHEADER bih;
BYTE *temp_bits;
PixelFormat dst_format;
if (!(bitmap->format == PixelFormat16bppRGB555 ||
bitmap->format == PixelFormat24bppRGB ||
bitmap->format == PixelFormat32bppRGB ||
bitmap->format == PixelFormat32bppPARGB))
{
BITMAPINFOHEADER bih;
BYTE *temp_bits;
PixelFormat dst_format;
hdc = CreateCompatibleDC(0);
/* we can't draw a bitmap of this format directly */
hdc = CreateCompatibleDC(0);
temp_hdc = TRUE;
temp_bitmap = TRUE;
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biWidth = bitmap->width;
bih.biHeight = -bitmap->height;
bih.biPlanes = 1;
bih.biBitCount = 32;
bih.biCompression = BI_RGB;
bih.biSizeImage = 0;
bih.biXPelsPerMeter = 0;
bih.biYPelsPerMeter = 0;
bih.biClrUsed = 0;
bih.biClrImportant = 0;
hbitmap = CreateDIBSection(hdc, (BITMAPINFO*)&bih, DIB_RGB_COLORS,
(void**)&temp_bits, NULL, 0);
if (bitmap->format & (PixelFormatAlpha|PixelFormatPAlpha))
dst_format = PixelFormat32bppPARGB;
else
dst_format = PixelFormat32bppRGB;
convert_pixels(bitmap->width, bitmap->height,
bitmap->width*4, temp_bits, dst_format, bitmap->image.palette,
bitmap->stride, bitmap->bits, bitmap->format,
bitmap->image.palette);
}
if (bitmap->format == PixelFormat16bppRGB555 ||
bitmap->format == PixelFormat24bppRGB)
dst_format = bitmap->format;
else if (bitmap->format & (PixelFormatAlpha|PixelFormatPAlpha))
dst_format = PixelFormat32bppPARGB;
else
{
if (bitmap->hbitmap)
hbitmap = bitmap->hbitmap;
else
{
GdipCreateHBITMAPFromBitmap(bitmap, &hbitmap, 0);
temp_bitmap = TRUE;
}
dst_format = PixelFormat32bppRGB;
hdc = bitmap->hdc;
temp_hdc = (hdc == 0);
}
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biWidth = bitmap->width;
bih.biHeight = -bitmap->height;
bih.biPlanes = 1;
bih.biBitCount = PIXELFORMATBPP(dst_format);
bih.biCompression = BI_RGB;
bih.biSizeImage = 0;
bih.biXPelsPerMeter = 0;
bih.biYPelsPerMeter = 0;
bih.biClrUsed = 0;
bih.biClrImportant = 0;
if (temp_hdc)
{
if (!hdc) hdc = CreateCompatibleDC(0);
old_hbm = SelectObject(hdc, hbitmap);
}
hbitmap = CreateDIBSection(hdc, (BITMAPINFO*)&bih, DIB_RGB_COLORS,
(void**)&temp_bits, NULL, 0);
convert_pixels(bitmap->width, bitmap->height,
bitmap->width*PIXELFORMATBPP(dst_format)/8, temp_bits, dst_format, bitmap->image.palette,
bitmap->stride, bitmap->bits, bitmap->format,
bitmap->image.palette);
old_hbm = SelectObject(hdc, hbitmap);
save_state = SaveDC(graphics->hdc);
@ -3493,14 +3468,9 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
RestoreDC(graphics->hdc, save_state);
if (temp_hdc)
{
SelectObject(hdc, old_hbm);
DeleteDC(hdc);
}
if (temp_bitmap)
DeleteObject(hbitmap);
SelectObject(hdc, old_hbm);
DeleteDC(hdc);
DeleteObject(hbitmap);
}
}
else if (image->type == ImageTypeMetafile && ((GpMetafile*)image)->hemf)
@ -7005,7 +6975,7 @@ GpStatus WINGDIPAPI GdipGetDC(GpGraphics *graphics, HDC *hdc)
stat = METAFILE_GetDC((GpMetafile*)graphics->image, hdc);
}
else if (!graphics->hdc ||
(graphics->image && graphics->image->type == ImageTypeBitmap && ((GpBitmap*)graphics->image)->format & PixelFormatAlpha))
(graphics->image && graphics->image->type == ImageTypeBitmap))
{
/* Create a fake HDC and fill it with a constant color. */
HDC temp_hdc;

View file

@ -40,7 +40,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdiplus);
HRESULT WINAPI WICCreateImagingFactory_Proxy(UINT, IWICImagingFactory**);
#define PIXELFORMATBPP(x) ((x) ? ((x) >> 8) & 255 : 24)
#define WMF_PLACEABLE_KEY 0x9ac6cdd7
static const struct
@ -1793,8 +1792,7 @@ static GpStatus get_screen_resolution(REAL *xres, REAL *yres)
GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT width, INT height, INT stride,
PixelFormat format, BYTE* scan0, GpBitmap** bitmap)
{
HBITMAP hbitmap=NULL;
INT row_size, dib_stride;
INT row_size;
BYTE *bits=NULL, *own_bits=NULL;
REAL xres, yres;
GpStatus stat;
@ -1815,56 +1813,20 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT width, INT height, INT stride,
if (stat != Ok) return stat;
row_size = (width * PIXELFORMATBPP(format)+7) / 8;
dib_stride = (row_size + 3) & ~3;
if(!scan0)
stride = dib_stride;
if (format & PixelFormatGDI && !(format & (PixelFormatAlpha|PixelFormatIndexed)) && !scan0)
{
char bmibuf[FIELD_OFFSET(BITMAPINFO, bmiColors[256])];
BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pbmi->bmiHeader.biWidth = width;
pbmi->bmiHeader.biHeight = -height;
pbmi->bmiHeader.biPlanes = 1;
/* FIXME: use the rest of the data from format */
pbmi->bmiHeader.biBitCount = PIXELFORMATBPP(format);
pbmi->bmiHeader.biCompression = BI_RGB;
pbmi->bmiHeader.biSizeImage = 0;
pbmi->bmiHeader.biXPelsPerMeter = 0;
pbmi->bmiHeader.biYPelsPerMeter = 0;
pbmi->bmiHeader.biClrUsed = 0;
pbmi->bmiHeader.biClrImportant = 0;
hbitmap = CreateDIBSection(0, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
if (!hbitmap) return GenericError;
stride = dib_stride;
}
if (scan0)
bits = scan0;
else
{
/* Not a GDI format; don't try to make an HBITMAP. */
if (scan0)
bits = scan0;
else
{
INT size = abs(stride) * height;
stride = (row_size + 3) & ~3;
own_bits = bits = calloc(1, size);
if (!own_bits) return OutOfMemory;
if (stride < 0)
bits += stride * (1 - height);
}
own_bits = bits = calloc(1, stride * height);
if (!own_bits) return OutOfMemory;
}
*bitmap = calloc(1, sizeof(GpBitmap));
if(!*bitmap)
{
DeleteObject(hbitmap);
free(own_bits);
return OutOfMemory;
}
@ -1882,8 +1844,6 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT width, INT height, INT stride,
(*bitmap)->format = format;
(*bitmap)->image.decoder = NULL;
(*bitmap)->image.encoder = NULL;
(*bitmap)->hbitmap = hbitmap;
(*bitmap)->hdc = NULL;
(*bitmap)->bits = bits;
(*bitmap)->stride = stride;
(*bitmap)->own_bits = own_bits;
@ -2071,8 +2031,6 @@ static void move_bitmap(GpBitmap *dst, GpBitmap *src, BOOL clobber_palette)
free(dst->bitmapbits);
free(dst->own_bits);
DeleteDC(dst->hdc);
DeleteObject(dst->hbitmap);
if (clobber_palette)
{
@ -2087,8 +2045,6 @@ static void move_bitmap(GpBitmap *dst, GpBitmap *src, BOOL clobber_palette)
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;
dst->own_bits = src->own_bits;
@ -2120,8 +2076,6 @@ static GpStatus free_image_data(GpImage *image)
{
free(((GpBitmap*)image)->bitmapbits);
free(((GpBitmap*)image)->own_bits);
DeleteDC(((GpBitmap*)image)->hdc);
DeleteObject(((GpBitmap*)image)->hbitmap);
if (((GpBitmap*)image)->metadata_reader)
IWICMetadataReader_Release(((GpBitmap*)image)->metadata_reader);
free(((GpBitmap*)image)->prop_item);
@ -2240,7 +2194,6 @@ GpStatus WINGDIPAPI GdipGetImageDimension(GpImage *image, REAL *width,
GpStatus WINGDIPAPI GdipGetImageGraphicsContext(GpImage *image,
GpGraphics **graphics)
{
HDC hdc;
GpStatus stat;
TRACE("%p %p\n", image, graphics);
@ -2248,27 +2201,7 @@ GpStatus WINGDIPAPI GdipGetImageGraphicsContext(GpImage *image,
if(!image || !graphics)
return InvalidParameter;
if (image->type == ImageTypeBitmap && ((GpBitmap*)image)->hbitmap)
{
hdc = ((GpBitmap*)image)->hdc;
if(!hdc){
hdc = CreateCompatibleDC(0);
SelectObject(hdc, ((GpBitmap*)image)->hbitmap);
((GpBitmap*)image)->hdc = hdc;
}
stat = GdipCreateFromHDC(hdc, graphics);
if (stat == Ok)
{
(*graphics)->image = image;
(*graphics)->image_type = image->type;
(*graphics)->xres = image->xres;
(*graphics)->yres = image->yres;
}
}
else if (image->type == ImageTypeMetafile)
if (image->type == ImageTypeMetafile)
stat = METAFILE_GetGraphicsContext((GpMetafile*)image, graphics);
else
stat = graphics_from_image(image, graphics);

View file

@ -2726,7 +2726,7 @@ static void test_fromMemoryBitmap(void)
ok(hdc != NULL, "got NULL hdc\n");
color = GetPixel(hdc, 0, 0);
todo_wine expect(0x0c0b0d, color);
expect(0x0c0b0d, color);
status = GdipReleaseDC(graphics, hdc);
expect(Ok, status);