mirror of https://github.com/fltk/fltk
This new fl_read_image() function for Windows is *much* faster than
reading individual pixels as before (STR #2387), but there is still room for improvement... git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@8048 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
parent
e1887bf09c
commit
ff4cafeb30
1
CHANGES
1
CHANGES
|
@ -1,5 +1,6 @@
|
|||
CHANGES IN FLTK 1.3.0
|
||||
|
||||
- Much faster fl_read_image() for Windows (STR #2387).
|
||||
- Added general Options dialog (STR #2471)
|
||||
- Fixed Compiling with mingw-w64 (STR #2308).
|
||||
- Fixed crashes when detecting illegal utf 8 sequences
|
||||
|
|
|
@ -36,10 +36,8 @@ fl_read_image(uchar *p, // I - Pixel buffer or NULL to allocate
|
|||
int w, // I - Width of area to read
|
||||
int h, // I - Height of area to read
|
||||
int alpha) { // I - Alpha value for image (0 for none)
|
||||
int x, y; // Looping vars
|
||||
int d; // Depth of image
|
||||
uchar *ptr; // Pointer in image data
|
||||
|
||||
int d; // Depth of image
|
||||
|
||||
// Allocate the image data array as needed...
|
||||
d = alpha ? 4 : 3;
|
||||
|
@ -49,24 +47,87 @@ fl_read_image(uchar *p, // I - Pixel buffer or NULL to allocate
|
|||
// Initialize the default colors/alpha in the whole image...
|
||||
memset(p, alpha, w * h * d);
|
||||
|
||||
// Grab all of the pixels in the image, one at a time...
|
||||
// MRS: there has to be a better way than this!
|
||||
for (y = 0, ptr = p; y < h; y ++) {
|
||||
for (x = 0; x < w; x ++, ptr += d) {
|
||||
COLORREF c = GetPixel(fl_gc, X + x, Y + y);
|
||||
// Grab all of the pixels in the image...
|
||||
|
||||
ptr[0] = (uchar)c;
|
||||
c >>= 8;
|
||||
ptr[1] = (uchar)c;
|
||||
c >>= 8;
|
||||
ptr[2] = (uchar)c;
|
||||
// Assure that we are not trying to read non-existing data. If it is so, the
|
||||
// function should still work, but the out-of-bounds part of the image is
|
||||
// untouched (initialized with the alpha value or 0 (black), resp.).
|
||||
|
||||
int ww = w; // We need the original width for output data line size
|
||||
|
||||
int shift_x = 0; // X target shift if X modified
|
||||
int shift_y = 0; // Y target shift if X modified
|
||||
|
||||
if (X < 0) {
|
||||
shift_x = -X;
|
||||
w += X;
|
||||
X = 0;
|
||||
}
|
||||
if (Y < 0) {
|
||||
shift_y = -Y;
|
||||
h += Y;
|
||||
Y = 0;
|
||||
}
|
||||
|
||||
if (h < 1 || w < 1) return p; // nothing to copy
|
||||
|
||||
int line_size = ((3*w+3)/4) * 4; // each line is aligned on a DWORD (4 bytes)
|
||||
uchar *dib = new uchar[line_size*h]; // create temporary buffer to read DIB
|
||||
|
||||
// fill in bitmap info for GetDIBits
|
||||
|
||||
BITMAPINFO bi;
|
||||
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bi.bmiHeader.biWidth = w;
|
||||
bi.bmiHeader.biHeight = -h; // negative => top-down DIB
|
||||
bi.bmiHeader.biPlanes = 1;
|
||||
bi.bmiHeader.biBitCount = 24; // 24 bits RGB
|
||||
bi.bmiHeader.biCompression = BI_RGB;
|
||||
bi.bmiHeader.biSizeImage = 0;
|
||||
bi.bmiHeader.biXPelsPerMeter = 0;
|
||||
bi.bmiHeader.biYPelsPerMeter = 0;
|
||||
bi.bmiHeader.biClrUsed = 0;
|
||||
bi.bmiHeader.biClrImportant = 0;
|
||||
|
||||
// copy bitmap from original DC (Window, Fl_Offscreen, ...)
|
||||
|
||||
HDC hdc = CreateCompatibleDC(fl_gc);
|
||||
HBITMAP hbm = CreateCompatibleBitmap(fl_gc,w,h);
|
||||
|
||||
int save_dc = SaveDC(hdc); // save context for cleanup
|
||||
SelectObject(hdc,hbm); // select bitmap
|
||||
BitBlt(hdc,0,0,w,h,fl_gc,X,Y,SRCCOPY); // copy image section to DDB
|
||||
|
||||
// copy RGB image data to the allocated DIB
|
||||
|
||||
GetDIBits(hdc, hbm, 0, h, dib, (BITMAPINFO *)&bi, DIB_RGB_COLORS);
|
||||
|
||||
// finally copy the image data to the user buffer
|
||||
|
||||
for (int j = 0; j<h; j++) {
|
||||
const uchar *src = dib + j * line_size; // source line
|
||||
uchar *tg = p + (j + shift_y) * d * ww + shift_x * d; // target line
|
||||
for (int i = 0; i<w; i++) {
|
||||
uchar b = *src++;
|
||||
uchar g = *src++;
|
||||
*tg++ = *src++; // R
|
||||
*tg++ = g; // G
|
||||
*tg++ = b; // B
|
||||
if (alpha)
|
||||
*tg++ = alpha; // alpha
|
||||
}
|
||||
}
|
||||
|
||||
// free used GDI and other structures
|
||||
|
||||
RestoreDC(hdc,save_dc); // reset DC
|
||||
DeleteDC(hdc);
|
||||
DeleteObject(hbm);
|
||||
delete[] dib; // delete DIB temporary buffer
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// End of "$Id$".
|
||||
//
|
||||
|
|
Loading…
Reference in New Issue