bugGNUstep - Bugs: bug #27882, image drawing code fails/crashes

 
 

You are not allowed to post comments on this tracker with your current authentication level.

bug #27882: image drawing code fails/crashes

Submitted by:  Richard Frith-Macdonald <CaS>
Submitted on:  Fri 30 Oct 2009 08:40:54 PM UTC  
 
Category: BackendSeverity: 3 - Normal
Item Group: NoneStatus: Fixed
Privacy: PublicAssigned to: None
Open/Closed: Closed

(Jump to the original submission Jump to the original submission)

Sat 05 Dec 2009 10:48:05 PM UTC, comment #6:

I closed this bug report, as you fixed the original problem. Alpha handling for Windows drawing has been a hack all the time. Probably it would be best to use the cairo backend on Windows in the long run.

Fred Kiefer <FredKiefer>
Project Member
Fri 27 Nov 2009 11:25:42 AM UTC, comment #5:

The current code is no longer crashing, but it doesn't look right.
My suspicion is that alpha handling in the windows backend needs a lot of investigation.

Richard Frith-Macdonald <CaS>
Project Member
Mon 09 Nov 2009 09:02:31 AM UTC, comment #4:

I haven't had time to do more work on this ... I don't really know if it's working or not.

Richard Frith-Macdonald <CaS>
Project Member
Sun 08 Nov 2009 03:33:15 PM UTC, comment #3:

Richard, what is the state of this bug report. You added the code below and improved it a lot. Does it work now?

Fred Kiefer <FredKiefer>
Project Member
Sun 01 Nov 2009 05:30:49 PM UTC, comment #2:

I am currently not working on my Windows virtual machine, but I hacked donw the following code based on Microsoft examples and other code in the windows backend. I don't expect it to work out of the box, but it should provide you with a starting point for that method.

- (NSDictionary *) GSReadRect: (NSRect)r
{
NSMutableDictionary *dict;
NSAffineTransform *matrix;
double x, y;
NSMutableData *data;
unsigned char *cdata;
unsigned char *bits;
int i = 0;
HDC hDC;
HDC hdcMemDC = NULL;
HBITMAP hbitmap = NULL;
BITMAP bmpScreen;
HGDIOBJ old;
RECT rcClient;
BITMAPFILEHEADER bmfHeader;
BITMAPINFOHEADER bi;
DWORD dwBmpSize;
HANDLE hDIB;
LPBITMAPINFOHEADER lpbi;

if (window == NULL)
{
NSLog(@"No window in GSReadRect");
return;
}

r = [ctm rectInMatrixSpace: r];
x = NSWidth(r);
y = NSHeight(r);

dict = [NSMutableDictionary dictionary];
[dict setObject: NSDeviceRGBColorSpace forKey: @"ColorSpace"];

[dict setObject: [NSNumber numberWithUnsignedInt: 8] forKey: @"BitsPerSample"];
[dict setObject: [NSNumber numberWithUnsignedInt: 32]
forKey: @"Depth"];
[dict setObject: [NSNumber numberWithUnsignedInt: 4]
forKey: @"SamplesPerPixel"];
[dict setObject: [NSNumber numberWithUnsignedInt: 1]
forKey: @"HasAlpha"];

matrix = [self GSCurrentCTM];
[matrix translateXBy: -r.origin.x - offset.x
yBy: r.origin.y + NSHeight(r) - offset.y];
[dict setObject: matrix forKey: @"Matrix"];

hDC = GetDC((HWND)window);
if (!hDC)
{
NSLog(@"No DC for window %d in GSReadRect. Error %d",
(int)window, GetLastError());
return nil;
}

// Create a compatible DC which is used in a BitBlt from the window DC
hdcMemDC = CreateCompatibleDC(hDC);
if (!hdcMemDC)
{
NSLog(@"No Compatible DC for window %d in GSReadRect. Error %d",
(int)window, GetLastError());
ReleaseDC((HWND)window, hDC);
return nil;
}

ReleaseDC((HWND)window, hDC);

hDC = [self getHDC];

// Get the client area for size calculation
rcClient = GSWindowRectToMS(self, r);

// Create a compatible bitmap from the Window DC
hbitmap = CreateCompatibleBitmap(hDC, rcClient.right - rcClient.left,
rcClient.bottom - rcClient.top);
if (!hbitmap)
{
NSLog(@"No Compatible bitmap for window %d in GSReadRect. Error %d",
(int)window, GetLastError());
ReleaseDC((HWND)window, hdcMemDC);
[self releaseHDC: hDC];
return nil;
}

// Select the compatible bitmap into the compatible memory DC.
old = SelectObject(hdcMemDC, hbitmap);
if (!old)
{
NSLog(@"SelectObject failed for window %d in GSReadRect. Error %d",
(int)window, GetLastError());
DeleteObject(hbitmap);
ReleaseDC((HWND)window, hdcMemDC);
[self releaseHDC: hDC];
return nil;
}

// Bit block transfer into our compatible memory DC.
if (!BitBlt(hdcMemDC,
0, 0,
rcClient.right - rcClient.left,
rcClient.bottom - rcClient.top,
hDC,
0, 0,
SRCCOPY))
{
NSLog(@"BitBlt failed for window %d in GSReadRect. Error %d",
(int)window, GetLastError());
DeleteObject(hbitmap);
ReleaseDC((HWND)window, hdcMemDC);
[self releaseHDC: hDC];
return nil;
}

// Get the BITMAP from the HBITMAP
GetObject(hbitmap, sizeof(BITMAP), &bmpScreen);

dwBmpSize = bmpScreen.bmWidth * 4 * bmpScreen.bmHeight;

hDIB = GlobalAlloc(GHND, dwBmpSize + sizeof(BITMAPINFOHEADER));
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
lpbi->biSize = sizeof(BITMAPINFOHEADER);
lpbi->biWidth = bmpScreen.bmWidth;
lpbi->biHeight = bmpScreen.bmHeight;
lpbi->biPlanes = 1;
lpbi->biBitCount = 32;
lpbi->biCompression = BI_RGB;
lpbi->biSizeImage = 0;
lpbi->biXPelsPerMeter = 0;
lpbi->biYPelsPerMeter = 0;
lpbi->biClrUsed = 0;
lpbi->biClrImportant = 0;

// Gets the "bits" from the bitmap and copies them into a buffer
// which is pointed to by lpbi
GetDIBits(hDC, hbitmap, 0,
(UINT)bmpScreen.bmHeight,
lpbi,
(BITMAPINFO *)lpbi, DIB_RGB_COLORS);

data = [NSMutableData dataWithLength: dwBmpSize];
if (data == nil)
{
DeleteObject(hbitmap);
ReleaseDC((HWND)window, hdcMemDC);
[self releaseHDC: hDC];
return nil;
}

// Copy to data
cdata = [data mutableBytes];
bits = (unsigned char *)lpbi + sizeof(BITMAPINFOHEADER);
while (i < dwBmpSize)
{
cdata[i+0] = bits[i+2];
cdata[i+1] = bits[i+1];
cdata[i+2] = bits[i+0];
cdata[i+3] = 0xFF;
i += 4;
}

//Unlock and Free the DIB from the heap
GlobalUnlock(hDIB);
GlobalFree(hDIB);

//Clean up
DeleteObject(hbitmap);
ReleaseDC((HWND)window, hdcMemDC);
[self releaseHDC: hDC];

[dict setObject: [NSValue valueWithSize: NSMakeSize(bmpScreen.bmWidth, bmpScreen.bmHeight)]
forKey: @"Size"];
[dict setObject: data forKey: @"Data"];

return dict;
}

Fred Kiefer <FredKiefer>
Project Member
Sat 31 Oct 2009 06:14:30 AM UTC, comment #1:

I spent some time trying to follow this under debug ... I think this is a missing GSReadRect implementation in the windows backend.

Richard Frith-Macdonald <CaS>
Project Member
Fri 30 Oct 2009 08:40:54 PM UTC, original submission:

The new code in -extractImageFrom:withRect: in GSThemeTools.m fails on mingw.
I think the -TIFFRepresentation method is failing (not sure though). In any case this seems to create a crash when we try to draw the image. Unfortunately I'm fairly clueless about image drawing in gui/back but I'm guessing this is a backend issue as it seems to work on mu gnu/linux system.

Richard Frith-Macdonald <CaS>
Project Member

 

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -unavailable- added by FredKiefer (Posted a comment)
  • -unavailable- added by CaS (Submitted the item)
  •  

    Do you think this task is very important?
    If so, you can click here to add your encouragement to it.
    This task has 0 encouragements so far.

    Only logged-in users can vote.

     

    Please enter the title of George Orwell's famous dystopian book (it's a date):

     

     

    Follow 2 latest changes.

    Date Changed By Updated Field Previous Value => Replaced By
    Sat 05 Dec 2009 10:48:05 PM UTCFredKieferStatusNone=>Fixed
      Open/ClosedOpen=>Closed

    Back to the top


    Powered by Savane 3.1-cleanup1