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

Group
 
 

bug #27882: image drawing code fails/crashes

Submitter:  Richard Frith-Macdonald <CaS>
Submitted:  Fri 30 Oct 2009 08:40:54 PM UTC
   
 
Category:  Backend Severity:  3 - Normal
Item Group:  None Status:  Fixed
Privacy:  Public Assigned to:  None
Open/Closed:  Closed
* Mandatory Fields

Add a New Comment Rich Markup
   

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>
Group 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>
Group 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>
Group 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>
Group 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>
Group 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>
Group 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>
Group Member

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

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

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only logged-in users can vote.

     

    Follow 2 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2009-12-05 FredKiefer StatusNone Fixed
        Open/ClosedOpen Closed

    Back to the top

    Powered by Savane 3.13-4448.
    Corresponding source code