I didn't like the performance of GetPixel() so I changed the win32 version to 
use GetDIBits and do the appropriate transformations.  I'm not sure of the real 
speed up but I went from 1-2 frames/sec to 12 and the performance issue shifted 
to opengl drawing to the screen.

I have a couple of issues with readimage().

1) It fills in alpha.  Since it does this it might as well take a transparency 
color so you don't have update alpha again.

2) Swapping of colors isn't necessary in some cases so to make it more generic 
it shouldn't do that.  However, I understand the reasoning and it makes it so 
all OS version of readimage() return the same thing.  I would propose 
indicating RGB or BRG to distinguish this.  So if you pass in RGB it will 
convert appropriately for all version of readimage().  Same with BRG.

Cheers,
Bruce


At any rate, here is the code.  I did some limited testing with both RGB.  RGBA 
is what I use in my application.

uchar *                         // O - Pixel buffer or NULL if failed
fltk::readimage(uchar *p,       // I - Pixel buffer or NULL to allocate
        PixelType type,         // Type of pixels to store (RGB and RGBA only 
now)
        const Rectangle& r,     // area to read
        int linedelta
) {
  int   x, y;                   // Looping vars
  int   X = r.x();
  int   Y = r.y();
  int   w = r.w();
  int   h = r.h();
  int delta = depth(type);
  int bitcount;
  int imgsize = w * h * 4;

  HBITMAP destBmp;
  HDC     destDC;
  HBITMAP oldBmp;
  BITMAPINFO *pBitmapInfo;
  uchar     bitmapInfoBuffer[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];

  if (delta != 3 && delta != 4)
      return readimage(p, type, r, linedelta);

  destBmp = CreateCompatibleBitmap(dc, w, h);
  destDC = CreateCompatibleDC(dc);
  pBitmapInfo = (BITMAPINFO *)bitmapInfoBuffer;

  if (destBmp == NULL || destDC == NULL)
      return NULL;

  memset((char *)pBitmapInfo, 0, sizeof(bitmapInfoBuffer));
  pBitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);

  pBitmapInfo->bmiHeader.biWidth = w;
    // make 0,0 upper left rather than bottom left
  pBitmapInfo->bmiHeader.biHeight = -h;

    // use aligned values so we don't get padded data
    // The real question is whether to force the caller to use allocate
    // 32 bits per pixel or not.  I say force since event 24 bits is
    // 24 * width + padding.
  pBitmapInfo->bmiHeader.biBitCount = 32;
  pBitmapInfo->bmiHeader.biPlanes = 1;
  pBitmapInfo->bmiHeader.biCompression = BI_RGB;
  pBitmapInfo->bmiHeader.biSizeImage = imgsize;

  oldBmp = (HBITMAP)SelectObject(destDC, destBmp);
  BitBlt(destDC, X, Y, w, h, dc, 0, 0, SRCCOPY);

    // Deselect since GetDIBits requires it
  SelectObject(destDC, oldBmp);

    // Read bmp into pixel buffer
  GetDIBits(destDC, destBmp, 0, h, p, pBitmapInfo, DIB_RGB_COLORS);

  DeleteDC(destDC);
  DeleteObject(destBmp);

    // Down convert to 3 byte pixels
  if (delta == 3)
  {
      uchar c1, c2, c3;

      if (imgsize >= (3 * 4))
      {
          c1 = p[0]; c2 = p[1]; c3 = p[2];
          p[0] = c3; p[2] = c1; p[1] = c2;

          c1 = p[4]; c2 = p[5]; c3 = p[6];
          p[3] = c3; p[4] = c1; p[5] = c2;

          c1 = p[8]; c2 = p[9]; c3 = p[10];
          p[6] = c3; p[7] = c1; p[8] = c2;
      } else if (imgsize == (2 * 4))
      {
          c1 = p[0]; c2 = p[1]; c3 = p[2];
          p[0] = c3; p[2] = c1; p[1] = c2;

          c1 = p[4]; c2 = p[5]; c3 = p[6];
          p[3] = c3; p[4] = c1; p[5] = c2;

          return p;
      } else if (imgsize == (1 * 4))
      {
          c1 = p[8]; c2 = p[9]; c3 = p[10];
          p[6] = c3; p[7] = c1; p[8] = c2;

          return p;
      }

        // the temp swap is really only necessary for the first 3 pixels overlap
      for (int i = 3 * 4, int j = 3 * 3; i < imgsize; j += 3, i += 4)
      {
          p[j] = p[i+2];
          p[j+1] = p[i+1];
          p[j+2] = p[i];
      }
  } else
  {
      uchar c;

      for (int i = 0; i < imgsize; i += 4)
      {
            // convert BGR to RGB
          c = p[i];
          p[i] = p[i+2];
          p[i+2] = c;
      }
  }

  return p;
}
_______________________________________________
fltk-dev mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-dev

Reply via email to