HBITMAP CopyScreenToBitmap(LPRECT lpRect, BYTE *pData, BITMAPINFO *pHeader)
{
    HDC         hScrDC, hMemDC;         // screen DC and memory DC
    HBITMAP     hBitmap, hOldBitmap;    // handles to deice-dependent bitmaps
    int         nX, nY, nX2, nY2;       // coordinates of rectangle to grab
    int         nWidth, nHeight;        // DIB width and height
    int         xScrn, yScrn;           // screen resolution

    // check for an empty rectangle
    if (IsRectEmpty(lpRect))
      return NULL;

    // create a DC for the screen and create
    // a memory DC compatible to screen DC   
    hScrDC = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
    hMemDC = CreateCompatibleDC(hScrDC);

    // get points of rectangle to grab
    nX  = lpRect->left;
    nY  = lpRect->top;
    nX2 = lpRect->right;
    nY2 = lpRect->bottom;

    // get screen resolution
    xScrn = GetDeviceCaps(hScrDC, HORZRES);
    yScrn = GetDeviceCaps(hScrDC, VERTRES);

    //make sure bitmap rectangle is visible
    if (nX < 0)
        nX = 0;
    if (nY < 0)
        nY = 0;
    if (nX2 > xScrn)
        nX2 = xScrn;
    if (nY2 > yScrn)
        nY2 = yScrn;

    nWidth  = nX2 - nX;
    nHeight = nY2 - nY;

    // create a bitmap compatible with the screen DC
    hBitmap = CreateCompatibleBitmap(hScrDC, nWidth, nHeight);

    // select new bitmap into memory DC
    hOldBitmap = (HBITMAP) SelectObject(hMemDC, hBitmap);

    // bitblt screen DC to memory DC
    BitBlt(hMemDC, 0, 0, nWidth, nHeight, hScrDC, nX, nY, SRCCOPY);

    // select old bitmap back into memory DC and get handle to
    // bitmap of the screen   
    hBitmap = (HBITMAP)  SelectObject(hMemDC, hOldBitmap);

    // Copy the bitmap data into the provided BYTE buffer
    GetDIBits(hScrDC, hBitmap, 0, nHeight, pData, pHeader, DIB_RGB_COLORS);

    // clean up
    DeleteDC(hScrDC);
    DeleteDC(hMemDC);

    // return handle to the bitmap
    return hBitmap;
}
示例#2
1
//-----------------------------------------------------------------------------
//	BugDlg_CompressScreenshot
//
//	Compress .BMP to .JPG, Delete .BMP
//-----------------------------------------------------------------------------
bool BugDlg_CompressScreenshot()
{
	if ( !g_bug_szScreenshot[0] )
	{
		return false;
	}

	bool bSuccess = false;
	HBITMAP hBitmap = NULL;
	HDC hDC = NULL;
	char *pBMPBits = NULL;

	CUtlBuffer buf( 0, 0 );

	hBitmap = (HBITMAP)LoadImage( NULL, g_bug_szScreenshot, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE );
	if ( !hBitmap )
		goto cleanUp;

	hDC = CreateCompatibleDC( NULL );
	if ( !hDC )
		goto cleanUp;

	BITMAPINFO bitmapInfo;
	ZeroMemory( &bitmapInfo, sizeof( BITMAPINFO ) );
	bitmapInfo.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );

	// populate the bmp info
	if ( !GetDIBits( hDC, hBitmap, 0, 0, NULL, &bitmapInfo, DIB_RGB_COLORS ) )
		goto cleanUp;

	pBMPBits = (char *)Sys_Alloc( bitmapInfo.bmiHeader.biSizeImage );
	if ( !pBMPBits )
		goto cleanUp;
	
	// could be bottom-up or top-down
	int nHeight = abs( bitmapInfo.bmiHeader.biHeight );

	if ( bitmapInfo.bmiHeader.biBitCount != 32 )
	{
		// unexpected format
		goto cleanUp;
	}

	if ( bitmapInfo.bmiHeader.biCompression != BI_RGB && bitmapInfo.bmiHeader.biCompression != BI_BITFIELDS )
	{
		// unexpected format
		goto cleanUp;
	}

	// don't want color masks
	bitmapInfo.bmiHeader.biCompression = BI_RGB;

	// get the raw bits
	if ( !GetDIBits( hDC, hBitmap, 0, nHeight, pBMPBits, &bitmapInfo, DIB_RGB_COLORS ) )
		goto cleanUp;

	JSAMPROW row_pointer[1]; 

	// compression data structure
	struct jpeg_compress_struct cinfo;
	ZeroMemory( &cinfo, sizeof( jpeg_compress_struct ) );

	// point at stderr
	struct jpeg_error_mgr jerr;
	cinfo.err = jpeg_std_error( &jerr );

	// create compressor
	jpeg_create_compress( &cinfo );

	// Hook CUtlBuffer to compression
	jpeg_UtlBuffer_dest( &cinfo, &buf );

	// image width and height, in pixels
	cinfo.image_width = bitmapInfo.bmiHeader.biWidth;
	cinfo.image_height = nHeight;
	cinfo.input_components = 3;
	cinfo.in_color_space = JCS_RGB;

	// Apply settings
	jpeg_set_defaults( &cinfo );
	jpeg_set_quality( &cinfo, 50, TRUE );

	// Start compressor
	jpeg_start_compress( &cinfo, TRUE);
	
	char *pRowBuffer = (char*)_alloca( bitmapInfo.bmiHeader.biWidth * 3 );
	row_pointer[0] = (JSAMPROW)pRowBuffer;

	// Write scanlines
	while ( cinfo.next_scanline < cinfo.image_height ) 
	{
		char *pSrc;
		if ( bitmapInfo.bmiHeader.biHeight < 0 )
		{
			// top down
			pSrc = &pBMPBits[cinfo.next_scanline * bitmapInfo.bmiHeader.biWidth * 4];
		}
		else
		{
			// bottom up
			pSrc = &pBMPBits[(nHeight-1 - cinfo.next_scanline) * bitmapInfo.bmiHeader.biWidth * 4];
		}
		
		// convert to BGR to RGB
		char *pDst = pRowBuffer;
		for ( int i=0; i<bitmapInfo.bmiHeader.biWidth; i++ )
		{
			pDst[0] = pSrc[2];
			pDst[1] = pSrc[1];
			pDst[2] = pSrc[0];
			pSrc += 4;
			pDst += 3;
		}		
		jpeg_write_scanlines( &cinfo, row_pointer, 1 );
	}

	// Finalize image
	jpeg_finish_compress( &cinfo );

	char jpgFilename[MAX_PATH];
	Sys_StripExtension( g_bug_szScreenshot, jpgFilename, sizeof( jpgFilename ) );
	Sys_AddExtension( ".jpg", jpgFilename, sizeof( jpgFilename ) );
	if ( !Sys_SaveFile( jpgFilename, buf.Base(), buf.TellMaxPut() ) )
		goto cleanUp;

	// remove the uncompressed version
	unlink( g_bug_szScreenshot );
	strcpy( g_bug_szScreenshot, jpgFilename );

	bSuccess = true;

cleanUp:
	if ( hBitmap )
		DeleteObject( hBitmap );
	if ( hDC )
		DeleteDC( hDC );
	if ( pBMPBits )
		Sys_Free( pBMPBits );

	return bSuccess;
}
示例#3
0
void createBMPFile(LPTSTR pszFile, PBITMAPINFO pbi, 
                  HBITMAP hBMP, HDC hDC) 
{ 
    
    HANDLE hf;                  // file handle 
    BITMAPFILEHEADER hdr;       // bitmap file-header 
    PBITMAPINFOHEADER pbih;     // bitmap info-header 
    LPBYTE lpBits;              // memory pointer 
    DWORD dwTotal;              // total count of bytes 
    DWORD cb;                   // incremental count of bytes 
    BYTE *hp;                   // byte pointer 
    DWORD dwTmp; 

    pbih = (PBITMAPINFOHEADER) pbi; 
    lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);

    if (!lpBits) 
         throw "Global alloc error";

    // Retrieve the color table (RGBQUAD array) and the bits 
    // (array of palette indices) from the DIB. 
    if (!GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight, lpBits, pbi, 
        DIB_RGB_COLORS)) 
    {
        throw "GetDIBits error";
    }

    // Create the .BMP file. 
    hf = CreateFile(pszFile, 
                   GENERIC_READ | GENERIC_WRITE, 
                   (DWORD) 0, 
                    NULL, 
                   CREATE_ALWAYS, 
                   FILE_ATTRIBUTE_NORMAL, 
                   (HANDLE) NULL); 
    if (hf == INVALID_HANDLE_VALUE) 
        throw "CreateFile error";
        
    hdr.bfType = 0x4d42;        // 0x42 = "B" 0x4d = "M" 
    // Compute the size of the entire file. 
    hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) + 
                 pbih->biSize + pbih->biClrUsed 
                 * sizeof(RGBQUAD) + pbih->biSizeImage); 
    hdr.bfReserved1 = 0; 
    hdr.bfReserved2 = 0; 

    // Compute the offset to the array of color indices. 
    hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + 
                    pbih->biSize + pbih->biClrUsed 
                    * sizeof (RGBQUAD); 

    // Copy the BITMAPFILEHEADER into the .BMP file. 
    if (!WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER), 
        (LPDWORD) &dwTmp,  NULL)) 
    {
        throw "WriteFile error 1";
       
    }

    // Copy the BITMAPINFOHEADER and RGBQUAD array into the file. 
    if (!WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER) 
                  + pbih->biClrUsed * sizeof (RGBQUAD), 
                  (LPDWORD) &dwTmp, ( NULL)) )
        throw "WriteFile error 2";

    // Copy the array of color indices into the .BMP file. 
    dwTotal = cb = pbih->biSizeImage; 
    hp = lpBits; 
    if (!WriteFile(hf, (LPSTR) hp, (int) cb, (LPDWORD) &dwTmp,NULL)) 
           throw "WriteFile error 3";

    // Close the .BMP file. 
     if (!CloseHandle(hf)) 
           throw "CloseFile error";

    // Free memory. 
    GlobalFree((HGLOBAL)lpBits);
}
示例#4
0
QPixmap QPixmap::fromWinHBITMAP(HBITMAP bitmap, HBitmapFormat format)
{
    // Verify size
    BITMAP bitmap_info;
    memset(&bitmap_info, 0, sizeof(BITMAP));

    int res = GetObject(bitmap, sizeof(BITMAP), &bitmap_info);
    if (!res) {
        qErrnoWarning("QPixmap::fromWinHBITMAP(), failed to get bitmap info");
        return QPixmap();
    }
    int w = bitmap_info.bmWidth;
    int h = bitmap_info.bmHeight;

    BITMAPINFO bmi;
    memset(&bmi, 0, sizeof(bmi));
    bmi.bmiHeader.biSize        = sizeof(BITMAPINFOHEADER);
    bmi.bmiHeader.biWidth       = w;
    bmi.bmiHeader.biHeight      = -h;
    bmi.bmiHeader.biPlanes      = 1;
    bmi.bmiHeader.biBitCount    = 32;
    bmi.bmiHeader.biCompression = BI_RGB;
    bmi.bmiHeader.biSizeImage   = w * h * 4;

    QImage result;
    // Get bitmap bits
    uchar *data = (uchar *) qMalloc(bmi.bmiHeader.biSizeImage);

    HDC display_dc = GetDC(0);
    if (GetDIBits(display_dc, bitmap, 0, h, data, &bmi, DIB_RGB_COLORS)) {

        QImage::Format imageFormat = QImage::Format_ARGB32_Premultiplied;
        uint mask = 0;
        if (format == NoAlpha) {
            imageFormat = QImage::Format_RGB32;
            mask = 0xff000000;
        }

        // Create image and copy data into image.
        QImage image(w, h, imageFormat);
        if (!image.isNull()) { // failed to alloc?
            int bytes_per_line = w * sizeof(QRgb);
            for (int y=0; y<h; ++y) {
                QRgb *dest = (QRgb *) image.scanLine(y);
                const QRgb *src = (const QRgb *) (data + y * bytes_per_line);
                for (int x=0; x<w; ++x) {
                    const uint pixel = src[x];
                    if ((pixel & 0xff000000) == 0 && (pixel & 0x00ffffff) != 0)
                        dest[x] = pixel | 0xff000000;
                    else
                        dest[x] = pixel | mask;
                }
            }
        }
        result = image;
    } else {
        qWarning("QPixmap::fromWinHBITMAP(), failed to get bitmap bits");
    }
    ReleaseDC(0, display_dc);
    qFree(data);
    return fromImage(result);
}
示例#5
0
文件: bitblt.c 项目: howard5888/wineT
BOOL MFDRV_StretchBlt( PHYSDEV devDst, INT xDst, INT yDst, INT widthDst,
		       INT heightDst, PHYSDEV devSrc, INT xSrc, INT ySrc,
		       INT widthSrc, INT heightSrc, DWORD rop )
{
    BOOL ret;
    DWORD len;
    METARECORD *mr;
    BITMAP BM;
    METAFILEDRV_PDEVICE *physDevSrc = (METAFILEDRV_PDEVICE *)devSrc;
#ifdef STRETCH_VIA_DIB
    LPBITMAPINFOHEADER lpBMI;
    WORD nBPP;
#endif
    HBITMAP hBitmap = GetCurrentObject(physDevSrc->hdc, OBJ_BITMAP);

    if (GetObjectW(hBitmap, sizeof(BITMAP), &BM) != sizeof(BITMAP))
    {
        WARN("bad bitmap object %p passed for hdc %p\n", hBitmap, physDevSrc->hdc);
        return FALSE;
    }
#ifdef STRETCH_VIA_DIB
    nBPP = BM.bmPlanes * BM.bmBitsPixel;
    if(nBPP > 8) nBPP = 24; /* FIXME Can't get 16bpp to work for some reason */
    len = sizeof(METARECORD) + 10 * sizeof(INT16)
            + sizeof(BITMAPINFOHEADER) + (nBPP <= 8 ? 1 << nBPP: 0) * sizeof(RGBQUAD)
              + DIB_GetDIBWidthBytes(BM.bmWidth, nBPP) * BM.bmHeight;
    if (!(mr = HeapAlloc( GetProcessHeap(), 0, len)))
	return FALSE;
    mr->rdFunction = META_DIBSTRETCHBLT;
    lpBMI=(LPBITMAPINFOHEADER)(mr->rdParm+10);
    lpBMI->biSize      = sizeof(BITMAPINFOHEADER);
    lpBMI->biWidth     = BM.bmWidth;
    lpBMI->biHeight    = BM.bmHeight;
    lpBMI->biPlanes    = 1;
    lpBMI->biBitCount  = nBPP;
    lpBMI->biSizeImage = DIB_GetDIBWidthBytes(BM.bmWidth, nBPP) * lpBMI->biHeight;
    lpBMI->biClrUsed   = nBPP <= 8 ? 1 << nBPP : 0;
    lpBMI->biCompression = BI_RGB;
    lpBMI->biXPelsPerMeter = MulDiv(GetDeviceCaps(physDevSrc->hdc,LOGPIXELSX),3937,100);
    lpBMI->biYPelsPerMeter = MulDiv(GetDeviceCaps(physDevSrc->hdc,LOGPIXELSY),3937,100);
    lpBMI->biClrImportant  = 0;                          /* 1 meter  = 39.37 inch */

    TRACE("MF_StretchBltViaDIB->len = %ld  rop=%lx  PixYPM=%ld Caps=%d\n",
	  len,rop,lpBMI->biYPelsPerMeter,GetDeviceCaps(physDevSrc->hdc, LOGPIXELSY));

    if (GetDIBits(physDevSrc->hdc, hBitmap, 0, (UINT)lpBMI->biHeight,
                  (LPSTR)lpBMI + DIB_BitmapInfoSize( (BITMAPINFO *)lpBMI,
                                                     DIB_RGB_COLORS ),
                  (LPBITMAPINFO)lpBMI, DIB_RGB_COLORS))
#else
    len = sizeof(METARECORD) + 15 * sizeof(INT16) + BM.bmWidthBytes * BM.bmHeight;
    if (!(mr = HeapAlloc( GetProcessHeap(), 0, len )))
	return FALSE;
    mr->rdFunction = META_STRETCHBLT;
    *(mr->rdParm +10) = BM.bmWidth;
    *(mr->rdParm +11) = BM.bmHeight;
    *(mr->rdParm +12) = BM.bmWidthBytes;
    *(mr->rdParm +13) = BM.bmPlanes;
    *(mr->rdParm +14) = BM.bmBitsPixel;
    TRACE("len = %ld  rop=%lx\n", len, rop);
    if (GetBitmapBits( hBitmap, BM.bmWidthBytes * BM.bmHeight, mr->rdParm + 15))
#endif
    {
      mr->rdSize = len / sizeof(INT16);
      *(mr->rdParm) = LOWORD(rop);
      *(mr->rdParm + 1) = HIWORD(rop);
      *(mr->rdParm + 2) = heightSrc;
      *(mr->rdParm + 3) = widthSrc;
      *(mr->rdParm + 4) = ySrc;
      *(mr->rdParm + 5) = xSrc;
      *(mr->rdParm + 6) = heightDst;
      *(mr->rdParm + 7) = widthDst;
      *(mr->rdParm + 8) = yDst;
      *(mr->rdParm + 9) = xDst;
      ret = MFDRV_WriteRecord( devDst, mr, mr->rdSize * 2);
    }
    else
        ret = FALSE;
    HeapFree( GetProcessHeap(), 0, mr);
    return ret;
}
示例#6
0
JNIEXPORT jlong JNICALL
Java_sun_font_FileFontStrike__1getGlyphImageFromWindows
(JNIEnv *env, jobject unused,
 jstring fontFamily, jint style, jint size, jint glyphCode, jboolean fm) {

    GLYPHMETRICS glyphMetrics;
    LOGFONTW lf;
    BITMAPINFO bmi;
    TEXTMETRIC textMetric;
    RECT rect;
    int bytesWidth, dibBytesWidth, extra, imageSize, dibImageSize;
    unsigned char* dibImage = NULL, *rowPtr, *pixelPtr, *dibPixPtr, *dibRowPtr;
    unsigned char r,g,b;
    unsigned char* igTable;
    GlyphInfo* glyphInfo = NULL;
    int nameLen;
    LPWSTR name;
    HFONT oldFont, hFont;
    MAT2 mat2;

    unsigned short width;
    unsigned short height;
    short advanceX;
    short advanceY;
    int topLeftX;
    int topLeftY;
    int err;
    int bmWidth, bmHeight;
    int x, y;
    HBITMAP hBitmap = NULL, hOrigBM;
    int gamma, orient;

    HWND hWnd = NULL;
    HDC hDesktopDC = NULL;
    HDC hMemoryDC = NULL;

    hWnd = GetDesktopWindow();
    hDesktopDC = GetWindowDC(hWnd);
    if (hDesktopDC == NULL) {
        return (jlong)0;
    }
    if (GetDeviceCaps(hDesktopDC, BITSPIXEL) < 15) {
        FREE_AND_RETURN;
    }

    hMemoryDC = CreateCompatibleDC(hDesktopDC);
    if (hMemoryDC == NULL || fontFamily == NULL) {
        FREE_AND_RETURN;
    }
    err = SetMapMode(hMemoryDC, MM_TEXT);
    if (err == 0) {
        FREE_AND_RETURN;
    }

    memset(&lf, 0, sizeof(LOGFONTW));
    lf.lfHeight = -size;
    lf.lfWeight = (style & 1) ? FW_BOLD : FW_NORMAL;
    lf.lfItalic = (style & 2) ? 0xff : 0;
    lf.lfCharSet = DEFAULT_CHARSET;
    lf.lfQuality = CLEARTYPE_QUALITY;
    lf.lfOutPrecision = OUT_TT_PRECIS;
    lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
    lf.lfPitchAndFamily = DEFAULT_PITCH;

    nameLen = (*env)->GetStringLength(env, fontFamily);
    name = (LPWSTR)alloca((nameLen+1)*2);
    if (name == NULL) {
       FREE_AND_RETURN;
    }
    (*env)->GetStringRegion(env, fontFamily, 0, nameLen, name);
    name[nameLen] = '\0';

    if (nameLen < (sizeof(lf.lfFaceName) / sizeof(lf.lfFaceName[0]))) {
        wcscpy(lf.lfFaceName, name);
    } else {
        FREE_AND_RETURN;
    }

    hFont = CreateFontIndirectW(&lf);
    if (hFont == NULL) {
        FREE_AND_RETURN;
    }
    oldFont = SelectObject(hMemoryDC, hFont);

    memset(&textMetric, 0, sizeof(TEXTMETRIC));
    err = GetTextMetrics(hMemoryDC, &textMetric);
    if (err == 0) {
        FREE_AND_RETURN;
    }
    memset(&glyphMetrics, 0, sizeof(GLYPHMETRICS));
    memset(&mat2, 0, sizeof(MAT2));
    mat2.eM11.value = 1; mat2.eM22.value = 1;
    err = GetGlyphOutline(hMemoryDC, glyphCode,
                          GGO_METRICS|GGO_GLYPH_INDEX,
                          &glyphMetrics,
                          0, NULL, &mat2);
    if (err == GDI_ERROR) {
        /* Probably no such glyph - ie the font wasn't the one we expected. */
        FREE_AND_RETURN;
    }

    width  = (unsigned short)glyphMetrics.gmBlackBoxX;
    height = (unsigned short)glyphMetrics.gmBlackBoxY;

    /* Don't handle "invisible" glyphs in this code */
    if (width <= 0 || height == 0) {
       FREE_AND_RETURN;
    }

    advanceX = glyphMetrics.gmCellIncX;
    advanceY = glyphMetrics.gmCellIncY;
    topLeftX = glyphMetrics.gmptGlyphOrigin.x;
    topLeftY = glyphMetrics.gmptGlyphOrigin.y;

    /* GetGlyphOutline pre-dates cleartype and I'm not sure that it will
     * account for all pixels touched by the rendering. Need to widen,
     * and also adjust by one the x position at which it is rendered.
     * The extra pixels of width are used as follows :
     * One extra pixel at the left and the right will be needed to absorb
     * the pixels that will be touched by filtering by GDI to compensate
     * for colour fringing.
     * However there seem to be some cases where GDI renders two extra
     * pixels to the right, so we add one additional pixel to the right,
     * and in the code that copies this to the image cache we test for
     * the (rare) cases when this is touched, and if its not reduce the
     * stated image width for the blitting loops.
     * For fractional metrics :
     * One extra pixel at each end to account for sub-pixel positioning used
     * when fractional metrics is on in LCD mode.
     * The pixel at the left is needed so the blitting loop can index into
     * that a byte at a time to more accurately position the glyph.
     * The pixel at the right is needed so that when such indexing happens,
     * the blitting still can use the same width.
     * Consequently the width that is specified for the glyph is one less
     * than that of the actual image.
     * Note that in the FM case as a consequence we need to adjust the
     * position at which GDI renders, and the declared width of the glyph
     * See the if (fm) {} cases in the code.
     * For the non-FM case, we not only save 3 bytes per row, but this
     * prevents apparent glyph overlapping which affects the rendering
     * performance of accelerated pipelines since it adds additional
     * read-back requirements.
     */
    width+=3;
    if (fm) {
        width+=1;
    }
    /* DIB scanline must end on a DWORD boundary. We specify 3 bytes per pixel,
     * so must round up as needed to a multiple of 4 bytes.
     */
    dibBytesWidth = bytesWidth = width*3;
    extra = dibBytesWidth % 4;
    if (extra != 0) {
        dibBytesWidth += (4-extra);
    }
    /* The glyph cache image must be a multiple of 3 bytes wide. */
    extra = bytesWidth % 3;
    if (extra != 0) {
        bytesWidth += (3-extra);
    }
    bmWidth = width;
    bmHeight = height;

    /* Must use desktop DC to create a bitmap of that depth */
    hBitmap = CreateCompatibleBitmap(hDesktopDC, bmWidth, bmHeight);
    if (hBitmap == NULL) {
        FREE_AND_RETURN;
    }
    hOrigBM = (HBITMAP)SelectObject(hMemoryDC, hBitmap);

    /* Fill in black */
    rect.left = 0;
    rect.top = 0;
    rect.right = bmWidth;
    rect.bottom = bmHeight;
    FillRect(hMemoryDC, (LPRECT)&rect, GetStockObject(BLACK_BRUSH));

    /* Set text color to white, background to black. */
    SetBkColor(hMemoryDC, RGB(0,0,0));
    SetTextColor(hMemoryDC, RGB(255,255,255));

    /* adjust rendering position */
    x = -topLeftX+1;
    if (fm) {
        x += 1;
    }
    y = topLeftY - textMetric.tmAscent;
    err = ExtTextOutW(hMemoryDC, x, y, ETO_GLYPH_INDEX|ETO_OPAQUE,
                (LPRECT)&rect, (LPCWSTR)&glyphCode, 1, NULL);
    if (err == 0) {
        FREE_AND_RETURN;
    }

    /* Now get the image into a DIB.
     * MS docs for GetDIBits says the compatible bitmap must not be
     * selected into a DC, so restore the original first.
     */
    SelectObject(hMemoryDC, hOrigBM);
    SelectObject(hMemoryDC, oldFont);
    DeleteObject(hFont);

    memset(&bmi, 0, sizeof(BITMAPINFO));
    bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
    bmi.bmiHeader.biWidth = width;
    bmi.bmiHeader.biHeight = -height;
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biBitCount = 24;
    bmi.bmiHeader.biCompression = BI_RGB;

    dibImage = SAFE_SIZE_ARRAY_ALLOC(malloc, dibBytesWidth, height);
    if (dibImage == NULL) {
        FREE_AND_RETURN;
    }
    dibImageSize = dibBytesWidth*height;
    memset(dibImage, 0, dibImageSize);

    err = GetDIBits(hMemoryDC, hBitmap, 0, height, dibImage,
                    &bmi, DIB_RGB_COLORS);

    if (err == 0) {        /* GetDIBits failed. */
        FREE_AND_RETURN;
    }

    err = SystemParametersInfo(SPI_GETFONTSMOOTHINGORIENTATION, 0, &orient, 0);
    if (err == 0) {
        FREE_AND_RETURN;
    }
    err = SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0, &gamma, 0);
    if (err == 0) {
        FREE_AND_RETURN;
    }
    igTable = getIGTable(gamma/10);
    if (igTable == NULL) {
        FREE_AND_RETURN;
    }

    /* Now copy glyph image into a GlyphInfo structure and return it.
     * NB the xadvance calculated here may be overwritten by the caller.
     * 1 is subtracted from the bitmap width to get the glyph width, since
     * that extra "1" was added as padding, so the sub-pixel positioning of
     * fractional metrics could index into it.
     */
    glyphInfo = (GlyphInfo*)SAFE_SIZE_STRUCT_ALLOC(malloc, sizeof(GlyphInfo),
            bytesWidth, height);
    if (glyphInfo == NULL) {
        FREE_AND_RETURN;
    }
    imageSize = bytesWidth*height;
    glyphInfo->cellInfo = NULL;
    glyphInfo->rowBytes = bytesWidth;
    glyphInfo->width = width;
    if (fm) {
        glyphInfo->width -= 1; // must subtract 1
    }
    glyphInfo->height = height;
    glyphInfo->advanceX = advanceX;
    glyphInfo->advanceY = advanceY;
    glyphInfo->topLeftX = (float)(topLeftX-1);
    if (fm) {
        glyphInfo->topLeftX -= 1;
    }
    glyphInfo->topLeftY = (float)-topLeftY;
    glyphInfo->image = (unsigned char*)glyphInfo+sizeof(GlyphInfo);
    memset(glyphInfo->image, 0, imageSize);

    /* DIB 24bpp data is always stored in BGR order, but we usually
     * need this in RGB, so we can't just memcpy and need to swap B and R.
     * Also need to apply inverse gamma adjustment here.
     * We re-use the variable "extra" to see if the last pixel is touched
     * at all. If its not we can reduce the glyph image width. This comes
     * into play in some cases where GDI touches more pixels than accounted
     * for by increasing width by two pixels over the B&W image. Whilst
     * the bytes are in the cache, it doesn't affect rendering performance
     * of the hardware pipelines.
     */
    extra = 0;
    if (fm) {
        extra = 1; // always need it.
    }
    dibRowPtr = dibImage;
    rowPtr = glyphInfo->image;
    for (y=0;y<height;y++) {
        pixelPtr = rowPtr;
        dibPixPtr = dibRowPtr;
        for (x=0;x<width;x++) {
            if (orient == FE_FONTSMOOTHINGORIENTATIONRGB) {
                b = *dibPixPtr++;
                g = *dibPixPtr++;
                r = *dibPixPtr++;
            } else {
                r = *dibPixPtr++;
                g = *dibPixPtr++;
                b = *dibPixPtr++;
            }
            *pixelPtr++ = igTable[r];
            *pixelPtr++ = igTable[g];
            *pixelPtr++ = igTable[b];
            if (!fm && (x==(width-1)) && (r|g|b)) {
                extra = 1;
            }
        }
        dibRowPtr += dibBytesWidth;
        rowPtr  += bytesWidth;
    }
    if (!extra) {
        glyphInfo->width -= 1;
    }

    free(dibImage);
    ReleaseDC(hWnd, hDesktopDC);
    DeleteObject(hMemoryDC);
    DeleteObject(hBitmap);

    return ptr_to_jlong(glyphInfo);
}
示例#7
0
static
Bool
winQueryScreenDIBFormat (ScreenPtr pScreen, BITMAPINFOHEADER *pbmih)
{
  winScreenPriv(pScreen);
  HBITMAP		hbmp;
#if CYGDEBUG
  LPDWORD		pdw = NULL;
#endif
  
  /* Create a memory bitmap compatible with the screen */
  hbmp = CreateCompatibleBitmap (pScreenPriv->hdcScreen, 1, 1);
  if (hbmp == NULL)
    {
      ErrorF ("winQueryScreenDIBFormat - CreateCompatibleBitmap failed\n");
      return FALSE;
    }
  
  /* Initialize our bitmap info header */
  ZeroMemory (pbmih, sizeof (BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD));
  pbmih->biSize = sizeof (BITMAPINFOHEADER);

  /* Get the biBitCount */
  if (!GetDIBits (pScreenPriv->hdcScreen,
		  hbmp,
		  0, 1,
		  NULL,
		  (BITMAPINFO*) pbmih,
		  DIB_RGB_COLORS))
    {
      ErrorF ("winQueryScreenDIBFormat - First call to GetDIBits failed\n");
      DeleteObject (hbmp);
      return FALSE;
    }

#if CYGDEBUG
  /* Get a pointer to bitfields */
  pdw = (DWORD*) ((CARD8*)pbmih + sizeof (BITMAPINFOHEADER));

  winDebug ("winQueryScreenDIBFormat - First call masks: %08x %08x %08x\n",
	  pdw[0], pdw[1], pdw[2]);
#endif

  /* Get optimal color table, or the optimal bitfields */
  if (!GetDIBits (pScreenPriv->hdcScreen,
		  hbmp,
		  0, 1,
		  NULL,
		  (BITMAPINFO*)pbmih,
		  DIB_RGB_COLORS))
    {
      ErrorF ("winQueryScreenDIBFormat - Second call to GetDIBits "
	      "failed\n");
      DeleteObject (hbmp);
      return FALSE;
    }

  /* Free memory */
  DeleteObject (hbmp);
  
  return TRUE;
}
LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
   switch( uMsg )
   {
      case WM_COMMAND :
              switch( LOWORD( wParam ) )
              {
                 case IDM_TEST :
                        {
                           BITMAPINFOHEADER  bi;
                           BITMAPINFOHEADER* lpbi;
                           HBITMAP           hBitmap;
                           HDC               hDC, hMemDC;
                           HANDLE            hDIB;

                           // Initialize the BITMAPINFOHEADER structure.
                           //...........................................
                           bi.biSize     = sizeof( BITMAPINFOHEADER );
                           bi.biWidth    = 50;
                           bi.biHeight   = 50;
                           bi.biPlanes   = 1;
                           bi.biBitCount = 4;
                           bi.biCompression   = BI_RGB;
                           bi.biSizeImage     = 0;
                           bi.biXPelsPerMeter = 0;
                           bi.biYPelsPerMeter = 0;
                           bi.biClrUsed       = 0;
                           bi.biClrImportant  = 0;

                           hDC = GetDC( hWnd );

                           // Create DIB.
                           //............
                           hBitmap = CreateDIBitmap( hDC, &bi, 0L, NULL, 
                                                     NULL, 0 );

                           // Allocate memory for BITMAPINFO structure.
                           //..........................................
                           hDIB    = GlobalAlloc( GHND, 
                                                  sizeof( BITMAPINFOHEADER )+
                                                  16 * sizeof( RGBQUAD ) );

                           lpbi = (BITMAPINFOHEADER*)GlobalLock( hDIB );

                           // Copy bi to top of BITMAPINFO structure.
                           //........................................
                           *lpbi = bi;

                           // Use GetDIBits() to init bi struct data.
                           //........................................
                           GetDIBits( hDC, hBitmap, 0, 50, NULL, 
                                      (LPBITMAPINFO)lpbi, DIB_RGB_COLORS );
                           GlobalUnlock( hDIB );

                           // Create a memory device context 
                           // and select the DIB into it.
                           //...............................
                           hMemDC = CreateCompatibleDC( hDC );
                           SelectObject( hMemDC, hBitmap );

                           // Paint on memory device context.
                           //................................
                           SelectObject( hMemDC, GetStockObject(BLACK_BRUSH));
                           Rectangle( hMemDC, 0, 0, 50, 50 );

                           SelectObject( hMemDC, GetStockObject(WHITE_BRUSH));
                           Ellipse( hMemDC, 0, 0, 50, 50 );
                           Ellipse( hMemDC, 10, 0, 40, 50 );
                           Ellipse( hMemDC, 20, 0, 30, 50 );

                           // Paint the bitmap on the display.
                           //.................................
                           BitBlt( hDC, 0, 0, 50, 50,
                                   hMemDC, 0, 0, SRCCOPY );

                           DeleteDC( hMemDC );
                           GlobalFree( hDIB );
                           ReleaseDC( hWnd, hDC );
                        }
                        break;

                 case IDM_ABOUT :
                        DialogBox( hInst, "AboutBox", hWnd, (DLGPROC)About );
                        break;

                 case IDM_EXIT :
                        DestroyWindow( hWnd );
                        break;
              }
              break;
      
      case WM_DESTROY :
              PostQuitMessage(0);
              break;

      default :
            return( DefWindowProc( hWnd, uMsg, wParam, lParam ) );
   }

   return( 0L );
}
示例#9
0
static void TextProcessor(INT hdlImage,CHAR *lpText)
{
	BYTE *lp;
	CHAR szTesto[1024];
	POINT pt;
	IMGHEADER *Img;
	HDC hDC,hDClone;
	HBITMAP hbCopy;
	BYTE *lpSorg;
	INT iLx,iLy;
	BITMAPINFOHEADER *BmpHeader;
	BITMAPINFO *BmpInfo;
	INT iAlt=12;
	INT iCol1=0;
	INT iCol2=-1;
	BOOL fBold=FALSE;

	// ----------------------------------------------------------------------------
	// Creo una zona di memoria tipo video delle dimensioni dell'immagine
	//
	//memcpy(&ImgHeader,memoLock(hdlImage),sizeof(IMGHEADER));
	printf("Elaborazione TextProcessor [%s]" CRLF,lpText); //Sleep(2000);
	//ehLogWrite("> %s" CRLF,lpText);
	if (!*lpText) return;

	Img=memoLock(hdlImage);
	BmpInfo=(BITMAPINFO *) &Img->bmiHeader;
	BmpHeader=(BITMAPINFOHEADER *) &Img->bmiHeader;
    iLy=BmpHeader->biHeight; if (iLy<0) iLy=-BmpHeader->biHeight;
    iLx=BmpHeader->biWidth;

    hDC=GetDC(NULL); hDClone=CreateCompatibleDC(hDC); 
	SetMapMode(hDClone, MM_TEXT);
	hbCopy = CreateCompatibleBitmap(hDC, iLx, iLy);
	SelectObject(hDClone, hbCopy);
	ReleaseDC(NULL,hDC);

    lpSorg=(BYTE *) Img;  lpSorg+=Img->Offset;

	// Scrivo l'immagine in questa zona di memoria
	if (StretchDIBits(hDClone, 
					  // Coordinate e dimensioni di stampa a video
					  0,0,
					  iLx, 
					  iLy,

					  // Coordinate e dimensioni di lettura nel sorgente
					  0,
					  iLy+1,
					  iLx,
					  -iLy,
					  lpSorg,
					  (BITMAPINFO *) &Img->bmiHeader,
					  DIB_RGB_COLORS, 
					  SRCCOPY) == GDI_ERROR) {printf("StretchDIBits Failed");}

	// Ci faccio quello che ci devo fare con i comandi
	lp=strtok(lpText,"|");
	*szTesto=0;
	ZeroFill(pt);
	while (lp)
	{
		//printf("[%s]" CRLF,lp); 

		if (!memcmp(lp,"TEXT=",5)) strcpy(szTesto,lp+5);
		if (!memcmp(lp,"PX=",3)) pt.x=atoi(lp+3);
		if (!memcmp(lp,"PY=",3)) pt.y=atoi(lp+3);
		if (!memcmp(lp,"ALT=",3)) iAlt=atoi(lp+3);
		if (!memcmp(lp,"COL=",4)) iCol1=ColorConvert(lp+4);
		if (!memcmp(lp,"BG=",3)) iCol2=ColorConvert(lp+3);
		if (!memcmp(lp,"BOLD=",5)) fBold=atoi(lp+5);
		
		if (*lp=='*') 
		{
			//printf("Stampo: %d,%d,%s" CRLF,pt.x,pt.y,szTesto);
			//ehLogWrite("Stampo: %d,%d,%s",pt.x,pt.y,szTesto);
			LPrint(hDClone,pt.x,pt.y,iCol1,iCol2,"Arial",iAlt,fBold,szTesto);
		}

		lp=strtok(NULL,"|");
	}

	// Mi riprendo la zona di memoria video e la rimetto nell'immagine
	//BmpHeader->biHeight*=-1;
	GetDIBits(
		hDClone,           // handle to device context
		hbCopy,      // handle to bitmap
		0,   // first scan line to set in destination bitmap
		iLy,   // number of scan lines to copy
		lpSorg,    // address of array for bitmap bits
		(BITMAPINFO *) &Img->bmiHeader, // address of structure with bitmap data
		DIB_RGB_COLORS        // RGB or palette index
		);
	
	if (!DeleteDC(hDClone)) 
	{
		ehLogWrite("Errore in cancellazione DC %d",GetLastError());
		ehExit("Errore in cancellazione DC");
	}

	if (!DeleteObject(hbCopy))
	{
		ehLogWrite("Errore in cancellazione Bitmap %d",GetLastError());
		ehExit("Errore in cancellazione Bitmap");
	}

	memoUnlockEx(hdlImage,"A5");
	IMGMirrorY(hdlImage);
	
	// Libero le risorse

	//TextOut(


}
示例#10
0
void PLWEMFDecoder::GetImage (PLBmpBase & Bmp)
{
	HPALETTE hpal = NULL;
  LPLOGPALETTE plogpal (0);

  if (GetBitsPerPixel() == 8) {
		plogpal = (LPLOGPALETTE)new PLBYTE[sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256)];
		memset(plogpal,0x0,sizeof(LOGPALETTE) + sizeof(PALETTEENTRY)*256);
		plogpal->palVersion = 0x300;
		plogpal->palNumEntries = 256;
		if (plogpal == NULL) {
			PLASSERT(false);
			raiseError (PL_ERRNO_MEMORY,"Cannot allocate palette.");
		}
    UINT pe = GetEnhMetaFilePaletteEntries(m_hemf, 0, NULL);
		GetEnhMetaFilePaletteEntries(m_hemf, pe, plogpal->palPalEntry);
	}

	// Setup a logical palette for our memory dc and also a
	// paintlib compatible palette for the paintlib bitmap
  PLPixel32 pPal[256];
	if (plogpal) {
		for (UINT i = 0; i < 256; i++) {
			pPal[i] = *(PLPixel32*)&plogpal->palPalEntry[i];
		}

		if ((hpal = CreatePalette((LPLOGPALETTE)plogpal))) {
			m_holdpal = SelectPalette(m_memdc, hpal, false);
			RealizePalette(m_memdc);
		}
		Bmp.SetPalette(pPal);
		delete [] plogpal;
	}

	// Play the metafile into the device context
	// First, setup a bounding rectangle and fill
	// the memory dc with white (some metafiles only
	// use a black pen to draw and have no actual fill
	// color set, This would cause a black on black
	// painting which is rather useless
	RECT rc;
	rc.left = rc.top = 0;
	rc.bottom = GetHeight();
	rc.right = GetWidth();

	FillRect(m_memdc,&rc,(HBRUSH)GetStockObject(WHITE_BRUSH));

	// Heeere we go....
	BOOL bres = PlayEnhMetaFile(m_memdc,m_hemf,&rc);

	// Finally, convert the Windows bitmap into a paintlib bitmap
	PLWinBmp& winbmp = dynamic_cast<PLWinBmp&>(Bmp);
	BITMAPINFO* pBMI = (BITMAPINFO*)winbmp.GetBMI();
	PLBYTE* pBits = (PLBYTE*)winbmp.GetBits();
	if (GetBitsPerPixel() == 8) {
		GetDIBits(m_dc, m_bm, 0, GetHeight(), winbmp.GetBits(), pBMI, DIB_RGB_COLORS);
	}
	else {
		GetDIBits(m_dc, m_bm, 0, GetHeight(), winbmp.GetBits(), pBMI, DIB_PAL_COLORS);
	}
}
示例#11
0
//////////////////////////////////////////////////////////////////////////////
// CMainFrame message handlers
void CMainFrame::OnEditPaste() 
{
	CDemoDoc *NewDoc=(CDemoDoc*)((CDemoApp*)AfxGetApp())->demoTemplate->OpenDocumentFile(NULL); 

	if (NewDoc)
	{
		if (OpenClipboard())
		{
			HANDLE hData=NULL;
			
			if (hData = GetClipboardData(((CDemoApp*)AfxGetApp())->GetCF())){ //custom CxImage object
				CxImage *newima = new CxImage();
				DWORD dwSize = GlobalSize(hData);
				if (dwSize) {
					BYTE *lpVoid = (BYTE *)GlobalLock(hData);
					newima->UnDump(lpVoid);
					GlobalUnlock(lpVoid);
				}
				NewDoc->image = newima;
			} else if (hData = GetClipboardData(CF_DIB)){ // check if bitmap
				CxImage *newima = new CxImage();
				newima->CreateFromHANDLE(hData);
				NewDoc->image = newima;
			} else  {		
#if CXIMAGE_SUPPORT_WMF
				if (hData = GetClipboardData(CF_ENHMETAFILE)) //check if metafile
				{
					HENHMETAFILE hMeta = (HENHMETAFILE)hData;
					ENHMETAHEADER emh;
					GetEnhMetaFileHeader(hMeta, sizeof(emh), &emh); 

					int	cx,cy;
					cx = (int)((emh.rclBounds.right - emh.rclBounds.left)/2.54);
					cy = (int)((emh.rclBounds.bottom - emh.rclBounds.top)/2.54);

					HDC hDC0 = ::GetDC(0); // screen dc
					HBITMAP hBitmap = CreateCompatibleBitmap(hDC0, cx, cy);
					HDC	hDC = CreateCompatibleDC(hDC0);	// memory dc compatible with screen
					::ReleaseDC(0, hDC0);	// don't need anymore. get rid of it.

					if (hDC && hBitmap){

						RECT rc = {0,0,cx,cy};
						int bpp = ::GetDeviceCaps(hDC, BITSPIXEL);

						HBITMAP hBitmapOld = (HBITMAP)SelectObject(hDC, hBitmap);

						// paint the background
						DWORD	dwBack = RGB(255, 255, 255); //GetSysColor(COLOR_WINDOW);
						DWORD OldColor = SetBkColor(hDC, dwBack);
						ExtTextOut(hDC, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
						SetBkColor(hDC, OldColor);

						// Play the Metafile into Memory DC
						BOOL bRet = PlayEnhMetaFile(hDC, hMeta,	&rc);

						SelectObject(hDC, hBitmapOld);

						CxImage *newima = new CxImage();
						if(bRet && newima->Create(cx, cy, bpp, CXIMAGE_FORMAT_WMF)){
							
							bRet = GetDIBits(hDC, hBitmap, 0,	(UINT)cy, newima->GetBits(),
								             (LPBITMAPINFO)newima->GetDIB(), DIB_RGB_COLORS);

							NewDoc->image = newima;
						}
						else
						{
							delete newima;
						}
					}
					if (hBitmap) DeleteObject(hBitmap);
					if (hDC) DeleteDC(hDC);
				}
#endif
			}
		}

		CloseClipboard();

		CString s;
		s.Format(_T("Clipboard Image %d"),((CDemoApp*)AfxGetApp())->m_nDocCount++);
		NewDoc->SetTitle(s);
		NewDoc->UpdateAllViews(0,WM_USER_NEWIMAGE);
		NewDoc->UpdateStatusBar();
	}
}
示例#12
0
/* EXPORT->HDumpGraf: dump a BMP image of current display into fname */
void HDumpGraf(char *fname)
{
   BITMAPFILEHEADER FileHeader;
   BITMAPINFOHEADER BitmapHeader;
   BITMAPINFO *Info;
   int ColorTableSize;
   int ImageSize;
   FILE *fp;
   char *img;
   HDC dc = GetDC(theWindow);
   HBITMAP temp = CreateCompatibleBitmap(memDC,1,1);
     
   SelectObject(memDC,temp);
     
   /* retrieve information about the bitmap */
   BitmapHeader.biSize = sizeof(BITMAPINFOHEADER);
   BitmapHeader.biBitCount = 0;
   GetDIBits(memDC,theBitmap,0,0,NULL,&BitmapHeader,BI_RGB);
     
   switch (BitmapHeader.biCompression) {
   case BI_RGB:
      if (BitmapHeader.biBitCount > 8) {
         ColorTableSize = 0;
      }
      else {
         ColorTableSize = BitmapHeader.biClrUsed*sizeof(RGBQUAD);
      }
      break;
   case BI_RLE8:
   case BI_RLE4:
      ColorTableSize = BitmapHeader.biClrUsed*sizeof(RGBQUAD); 
      break;
   case BI_BITFIELDS:
      ColorTableSize = 3*sizeof(DWORD);
   }
     
   Info = (BITMAPINFO *) New(&gcheap,sizeof(BITMAPINFOHEADER) + ColorTableSize);
   memcpy(Info,&BitmapHeader,sizeof(BITMAPINFOHEADER));
     
   ImageSize = BitmapHeader.biSizeImage;
   img = New(&gcheap,ImageSize);
     
   GetDIBits(memDC,theBitmap,0,ClientRect.bottom,img,Info,BI_RGB);
     
   FileHeader.bfType = 0x4d42;  /* 'BM' */
   FileHeader.bfSize = sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER) + 
      ImageSize + ColorTableSize;
   FileHeader.bfReserved1 = FileHeader.bfReserved2 = 0;
   FileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + ColorTableSize; 
     
   fp = fopen(fname,"wb");
   fwrite(&FileHeader,1,sizeof(BITMAPFILEHEADER),fp);
   fwrite(Info,1,sizeof(BITMAPINFOHEADER) + ColorTableSize,fp);
   fwrite(img,1,ImageSize,fp);
   fclose(fp);

   SelectObject(memDC,theBitmap);
   DeleteObject(temp);
   Dispose(&gcheap,Info);
   Dispose(&gcheap,img);
}
HBITMAP MonitorImageSource::GetImage(int width, int height)
{
   DISPLAY_DEVICE named_device;
   named_device.cb = sizeof(DISPLAY_DEVICE);

   for (int deviceId = 0;;deviceId++) {
      DISPLAY_DEVICE device;
      device.cb = sizeof(DISPLAY_DEVICE);

      BOOL result = ::EnumDisplayDevices(NULL, deviceId, &device, 0);
      if (result == 0) break;

      if (device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) {
         result = ::EnumDisplayDevices(device.DeviceName, 0, &named_device, 0);
      }
   }

   HBITMAP hbmScreen = NULL;
   BITMAP bmpScreen;

   // Retrieve the handle to a display device context for the client 
   // area of the window.
   Win32::DisplayDeviceContext hdcScreen("DISPLAY");
   Win32::WindowDeviceContext hdcWindow(::GetDesktopWindow());

   // Create a compatible DC which is used in a BitBlt from the window DC
   Win32::MemoryDeviceContext hdcMemDC(hdcWindow); 

   //This is the best stretch mode
   ::SetStretchBltMode(hdcWindow,HALFTONE);

   //The source DC is the entire screen and the destination DC is the current window (HWND)
   if(!::StretchBlt(hdcWindow, 
      0,0, width, height, 
      hdcScreen,
      0, 0,
      GetSystemMetrics(SM_CXVIRTUALSCREEN),
      GetSystemMetrics(SM_CYVIRTUALSCREEN),
      SRCCOPY))
   {
   }

   // Create a compatible bitmap from the Window DC
   hbmScreen = CreateCompatibleBitmap(hdcWindow, width, height);
   if(!hbmScreen)
   {
      //TODO: Error handling
   }

   // Select the compatible bitmap into the compatible memory DC.
   SelectObject(hdcMemDC,hbmScreen);

   // Bit block transfer into our compatible memory DC.
   if(!BitBlt(hdcMemDC, 
      0,0, width, height, 
      hdcWindow, 
      0,0,
      SRCCOPY))
   {
      //TODO: Error handling
   }

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

   BITMAPFILEHEADER   bmfHeader;    
   BITMAPINFOHEADER   bi;

   bi.biSize = sizeof(BITMAPINFOHEADER);    
   bi.biWidth = bmpScreen.bmWidth;    
   bi.biHeight = bmpScreen.bmHeight;  
   bi.biPlanes = 1;    
   bi.biBitCount = 32;    
   bi.biCompression = BI_RGB;    
   bi.biSizeImage = 0;  
   bi.biXPelsPerMeter = 0;    
   bi.biYPelsPerMeter = 0;    
   bi.biClrUsed = 0;    
   bi.biClrImportant = 0;

   DWORD dwBmpSize = ((bmpScreen.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmpScreen.bmHeight;

   // Starting with 32-bit Windows, GlobalAlloc and LocalAlloc are implemented as wrapper functions that 
   // call HeapAlloc using a handle to the process's default heap. Therefore, GlobalAlloc and LocalAlloc 
   // have greater overhead than HeapAlloc.
   HANDLE hDIB = GlobalAlloc(GHND,dwBmpSize); 
   char *lpbitmap = (char *)GlobalLock(hDIB);    

   // Gets the "bits" from the bitmap and copies them into a buffer 
   // which is pointed to by lpbitmap.
   GetDIBits(hdcWindow, hbmScreen, 0,
      (UINT)bmpScreen.bmHeight,
      lpbitmap,
      (BITMAPINFO *)&bi, DIB_RGB_COLORS);

   // A file is created, this is where we will save the screen capture.
   HANDLE hFile = CreateFile(L"captureqwsx.bmp",
      GENERIC_WRITE,
      0,
      NULL,
      CREATE_ALWAYS,
      FILE_ATTRIBUTE_NORMAL, NULL);   

   // Add the size of the headers to the size of the bitmap to get the total file size
   DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

   //Offset to where the actual bitmap bits start.
   bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER); 

   //Size of the file
   bmfHeader.bfSize = dwSizeofDIB; 

   //bfType must always be BM for Bitmaps
   bmfHeader.bfType = 0x4D42; //BM   

   DWORD dwBytesWritten = 0;
   WriteFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL);
   WriteFile(hFile, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL);
   WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &dwBytesWritten, NULL);

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

   //Close the handle for the file that was created
   CloseHandle(hFile);

   return 0;
};
示例#14
0
文件: fbx.c 项目: coffee8651/turbovnc
int fbx_init(fbx_struct *fb, fbx_wh wh, int width_, int height_, int useShm)
{
	int width, height;
	int rmask, gmask, bmask, ps, i;
	#ifdef _WIN32
	BMINFO bminfo;  HBITMAP hmembmp=0;  RECT rect;  HDC hdc=NULL;
	#else
	XWindowAttributes xwa;  int shmok=1, alphaFirst, pixmap=0;
	#endif

	if(!fb) _throw("Invalid argument");

	#ifdef _WIN32

	if(!wh) _throw("Invalid argument");
	_w32(GetClientRect(wh, &rect));
	if(width_>0) width=width_;
	else
	{
		width=rect.right-rect.left;  if(width<=0) width=MINWIDTH;
	}
	if(height_>0) height=height_;
	else
	{
		height=rect.bottom-rect.top;  if(height<=0) height=MINHEIGHT;
	}
	if(fb->wh==wh)
	{
		if(width==fb->width && height==fb->height && fb->hmdc && fb->hdib
			&& fb->bits)
			return 0;
		else if(fbx_term(fb)==-1) return -1;
	}
	memset(fb, 0, sizeof(fbx_struct));
	fb->wh=wh;

	_w32(hdc=GetDC(fb->wh));
	_w32(fb->hmdc=CreateCompatibleDC(hdc));
	_w32(hmembmp=CreateCompatibleBitmap(hdc, width, height));
	_w32(GetDeviceCaps(hdc, RASTERCAPS)&RC_BITBLT);
	_w32(GetDeviceCaps(fb->hmdc, RASTERCAPS)&RC_DI_BITMAP);
	bminfo.bmi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
	bminfo.bmi.bmiHeader.biBitCount=0;
	_w32(GetDIBits(fb->hmdc, hmembmp, 0, 1, NULL, &bminfo.bmi, DIB_RGB_COLORS));
	_w32(GetDIBits(fb->hmdc, hmembmp, 0, 1, NULL, &bminfo.bmi, DIB_RGB_COLORS));
	_w32(DeleteObject(hmembmp));  hmembmp=0;
		/* (we only needed it to get the screen properties) */
	ps=bminfo.bmi.bmiHeader.biBitCount/8;
	if(width>0) bminfo.bmi.bmiHeader.biWidth=width;
	if(height>0) bminfo.bmi.bmiHeader.biHeight=height;
	fb->width=bminfo.bmi.bmiHeader.biWidth;
	fb->height=bminfo.bmi.bmiHeader.biHeight;

	if(ps<3)
	{
		/* Make the buffer BGRA */
		bminfo.bmi.bmiHeader.biCompression=BI_BITFIELDS;
		bminfo.bmi.bmiHeader.biBitCount=32;
		ps=4;
		(*(DWORD *)&bminfo.bmi.bmiColors[0])=0xFF0000;
		(*(DWORD *)&bminfo.bmi.bmiColors[1])=0xFF00;
		(*(DWORD *)&bminfo.bmi.bmiColors[2])=0xFF;
	}

	fb->pitch=BMPPAD(fb->width*ps);  /* Windoze bitmaps are always padded */

	if(bminfo.bmi.bmiHeader.biCompression==BI_BITFIELDS)
	{
		rmask=(*(DWORD *)&bminfo.bmi.bmiColors[0]);
		gmask=(*(DWORD *)&bminfo.bmi.bmiColors[1]);
		bmask=(*(DWORD *)&bminfo.bmi.bmiColors[2]);
	}
	else
	{
		rmask=0xFF0000;
		gmask=0xFF00;
		bmask=0xFF;
	}

	fb->format=-1;
	for(i=0; i<FBX_FORMATS; i++)
		if(rmask==fbx_rmask[i] && gmask==fbx_gmask[i] && bmask==fbx_bmask[i]
			&& ps==fbx_ps[i] && fbx_alphafirst[i]==0) fb->format=i;
	if(fb->format==-1) _throw("Display has unsupported pixel format");

	bminfo.bmi.bmiHeader.biHeight=-bminfo.bmi.bmiHeader.biHeight;
		/* (our convention is top-down) */
	_w32(fb->hdib=CreateDIBSection(hdc, &bminfo.bmi, DIB_RGB_COLORS,
		(void **)&fb->bits, NULL, 0));
	_w32(SelectObject(fb->hmdc, fb->hdib));
	ReleaseDC(fb->wh, hdc);
	return 0;

	finally:
	if(hmembmp) DeleteObject(hmembmp);
	if(hdc) ReleaseDC(fb->wh, hdc);

	#else

	if(!wh.dpy || !wh.d) _throw("Invalid argument");
	if(wh.v)
	{
		_x11(XGetGeometry(wh.dpy, wh.d, &xwa.root, &xwa.x, &xwa.y,
			(unsigned int *)&xwa.width, (unsigned int *)&xwa.height,
			(unsigned int *)&xwa.border_width, (unsigned int *)&xwa.depth));
		xwa.visual=wh.v;
		useShm=0;
		pixmap=1;
	}
	else
	{
		_x11(XGetWindowAttributes(wh.dpy, wh.d, &xwa));
	}
	if(width_>0) width=width_;  else width=xwa.width;
	if(height_>0) height=height_;  else height=xwa.height;
	if(fb->wh.dpy==wh.dpy && fb->wh.d==wh.d)
	{
		if(width==fb->width && height==fb->height && fb->xi && fb->xgc && fb->bits)
			return 0;
		else if(fbx_term(fb)==-1) return -1;
	}
	memset(fb, 0, sizeof(fbx_struct));
	fb->wh.dpy=wh.dpy;  fb->wh.d=wh.d;

	#ifdef USESHM
	if(!useShm)
	{
		static int alreadyWarned=0;
		if(!alreadyWarned && warningFile)
		{
			fprintf(warningFile, "[FBX] Disabling shared memory blitting\n");
			alreadyWarned=1;
		}
	}
	if(useShm && XShmQueryExtension(fb->wh.dpy))
	{
		static int alreadyWarned=0;
		fb->shminfo.shmid=-1;
		if(!(fb->xi=XShmCreateImage(fb->wh.dpy, xwa.visual, xwa.depth,
			ZPixmap, NULL, &fb->shminfo, width, height)))
		{
			useShm=0;  goto noshm;
		}
		if((fb->shminfo.shmid=shmget(IPC_PRIVATE,
			fb->xi->bytes_per_line*fb->xi->height+1, IPC_CREAT|0777))==-1)
		{
			useShm=0;  XDestroyImage(fb->xi);  goto noshm;
		}
		if((fb->shminfo.shmaddr=fb->xi->data
			=(char *)shmat(fb->shminfo.shmid, 0, 0))==(char *)-1)
		{
			useShm=0;  XDestroyImage(fb->xi);
			shmctl(fb->shminfo.shmid, IPC_RMID, 0);  goto noshm;
		}
		fb->shminfo.readOnly=False;
		XLockDisplay(fb->wh.dpy);
		XSync(fb->wh.dpy, False);
		prevHandler=XSetErrorHandler(xhandler);
		extok=1;
		serial=NextRequest(fb->wh.dpy);
		XShmAttach(fb->wh.dpy, &fb->shminfo);
		XSync(fb->wh.dpy, False);
		XSetErrorHandler(prevHandler);
		shmok=extok;
		if(!alreadyWarned && !shmok && warningFile)
		{
			fprintf(warningFile,
				"[FBX] WARNING: MIT-SHM extension failed to initialize (this is normal on a\n");
			fprintf(warningFile,
				"[FBX]    remote connection.)  Will use X Pixmap drawing instead.\n");
			alreadyWarned=1;
		}
		XUnlockDisplay(fb->wh.dpy);
		if(shmok)
		{
			char *env=getenv("FBX_USESHMPIXMAPS");
			if(env && !strcmp(env, "1"))
			{
				static int alreadyWarned=0;
				if(!alreadyWarned && warningFile)
				{
					fprintf(warningFile, "[FBX] Using MIT-SHM pixmaps\n");
					alreadyWarned=1;
				}
				fb->pm=XShmCreatePixmap(fb->wh.dpy, fb->wh.d, fb->shminfo.shmaddr,
					&fb->shminfo, width, height, xwa.depth);
				if(!fb->pm) shmok=0;
			}
		}
		shmctl(fb->shminfo.shmid, IPC_RMID, 0);
		if(!shmok)
		{
			useShm=0;  XDestroyImage(fb->xi);  shmdt(fb->shminfo.shmaddr);
			shmctl(fb->shminfo.shmid, IPC_RMID, 0);  goto noshm;
		}
		fb->xattach=1;  fb->shm=1;
	}
	else if(useShm)
	{
		static int alreadyWarned=0;
		if(!alreadyWarned && warningFile)
		{
			fprintf(warningFile,
				"[FBX] WARNING: MIT-SHM extension not available.  Will use X pixmap\n");
			fprintf(warningFile, "[FBX]    drawing instead.\n");
			alreadyWarned=1;
		}
		useShm=0;
	}
	noshm:
	if(!useShm)
	#endif
	{
		if(!pixmap)
			_x11(fb->pm=XCreatePixmap(fb->wh.dpy, fb->wh.d, width, height,
				xwa.depth));
		_x11(fb->xi=XCreateImage(fb->wh.dpy, xwa.visual, xwa.depth, ZPixmap, 0,
			NULL, width, height, 8, 0));
		if((fb->xi->data=(char *)malloc(fb->xi->bytes_per_line*fb->xi->height+1))
			==NULL)
			_throw("Memory allocation error");
	}
	ps=fb->xi->bits_per_pixel/8;
	fb->width=fb->xi->width;
	fb->height=fb->xi->height;
	fb->pitch=fb->xi->bytes_per_line;
	if(fb->width!=width || fb->height!=height)
		_throw("Bitmap returned does not match requested size");
	rmask=fb->xi->red_mask;  gmask=fb->xi->green_mask;  bmask=fb->xi->blue_mask;
	alphaFirst=0;
	if(fb->xi->byte_order==MSBFirst)
	{
		if(ps<4)
		{
			rmask=fb->xi->blue_mask;  gmask=fb->xi->green_mask;
			bmask=fb->xi->red_mask;
		}
		else alphaFirst=1;
	}

	fb->format=-1;
	for(i=0; i<FBX_FORMATS; i++)
		if(rmask==fbx_rmask[i] && gmask==fbx_gmask[i] && bmask==fbx_bmask[i]
			&& ps==fbx_ps[i] && fbx_alphafirst[i]==alphaFirst) fb->format=i;
	if(fb->format==-1) _throw("Display has unsupported pixel format");

	fb->bits=fb->xi->data;
	fb->pixmap=pixmap;
	_x11(fb->xgc=XCreateGC(fb->wh.dpy, fb->pm? fb->pm:fb->wh.d, 0, NULL));
	return 0;

	finally:

	#endif

	fbx_term(fb);
	return -1;
}
示例#15
0
/*
	Takes a screenshot of the screen and saves it in memory
*/
int takescreenshot(unsigned char **screenshotbuffer,int *screenshotbuffersize){
	//declaring & initializing needed vars
	HDC screendc = NULL;
	HDC compatiblescreendc = NULL;
	HBITMAP compatiblebitmap = NULL;
	HGDIOBJ selectedobject = NULL;
	BOOL bitbltresult = FALSE;
	int getobjectresult = 0;
	BITMAP finalbmp = {0};
	BITMAPFILEHEADER bmfileheader = {0};    
	BITMAPINFOHEADER bminfoheader = {0};
	DWORD dwBmpSize = 0;
	HANDLE hDIB = NULL;
	unsigned char *lpbitmap = NULL;
	int getdibitsresult = 0;	
	DWORD dwSizeofDIB = 0;
	int screenwidth = 0;
	int screenheight = 0;
	int leftxscreenpos = 0;
	int leftyscreenpos = 0;	
	char currentpath[MAX_PATH] = {0};

	//left side virtual screen coordinates
	leftxscreenpos = GetSystemMetrics(SM_XVIRTUALSCREEN);
	//top side virtual screen coordinates
	leftyscreenpos = GetSystemMetrics(SM_YVIRTUALSCREEN);	
	//width in pixels of the virtual screen
	screenwidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
	//height in pixels of the virtual screen
	screenheight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
	/*actually take the screenshot*/
	screendc = GetDC(NULL); 
	if(screendc == NULL){
		outputerror(DBG_ERROR,"%s\n","takescreenshot::GetDC() Failed");
		return 1;
	}
	compatiblescreendc = CreateCompatibleDC(screendc);
	if(compatiblescreendc == NULL){
		outputerror(DBG_ERROR,"%s\n","takescreenshot::CreateCompatibleDC() Failed");
		ReleaseDC(NULL,screendc);
		return 1;
	}
	compatiblebitmap = CreateCompatibleBitmap(screendc,screenwidth,screenheight);
	if(compatiblebitmap == NULL){
		outputerror(DBG_ERROR,"%s\n","takescreenshot::CreateCompatibleBitmap() Failed");
		ReleaseDC(NULL,screendc);
		DeleteDC(compatiblescreendc);
		return 1;
	}
	selectedobject = SelectObject(compatiblescreendc,compatiblebitmap);
	if(selectedobject == NULL || selectedobject == HGDI_ERROR){
		outputerror(DBG_ERROR,"%s\n","takescreenshot::SelectObject() Failed");
		ReleaseDC(NULL,screendc);
		DeleteDC(compatiblescreendc);
		DeleteObject(compatiblebitmap);
		return 1;
	}
	bitbltresult = BitBlt(compatiblescreendc,0,0,screenwidth,screenheight,screendc,leftxscreenpos,leftyscreenpos,SRCCOPY);
	if(bitbltresult == 0){
		outputerror(DBG_ERROR,"%s %d\n","takescreenshot::BitBlt() Failed", GetLastError());
		ReleaseDC(NULL,screendc);
		DeleteDC(compatiblescreendc);
		DeleteObject(compatiblebitmap);		
		return 1;
	}
	/*save the screenshot to file*/
	getobjectresult = GetObject(compatiblebitmap,sizeof(BITMAP),&finalbmp);
	if(getobjectresult == 0){
		outputerror(DBG_ERROR,"%s\n","takescreenshot::GetObject() Failed");
		ReleaseDC(NULL,screendc);
		DeleteDC(compatiblescreendc);
		DeleteObject(compatiblebitmap);
		return 1;
	}

	//bmp file format good read: http://en.wikipedia.org/wiki/BMP_file_format
	bminfoheader.biSize = sizeof(BITMAPINFOHEADER);    
    bminfoheader.biWidth = screenwidth;    
    bminfoheader.biHeight = screenheight;  
    bminfoheader.biPlanes = 1;    
    bminfoheader.biBitCount = 32;    
    bminfoheader.biCompression = BI_RGB;    
    bminfoheader.biSizeImage = 0;  
    bminfoheader.biXPelsPerMeter = 0;    
    bminfoheader.biYPelsPerMeter = 0;    
    bminfoheader.biClrUsed = 0;    
    bminfoheader.biClrImportant = 0;

	dwBmpSize = ((screenwidth * bminfoheader.biBitCount + 31) / 32) * 4 * screenheight;

	hDIB = GlobalAlloc(GHND,dwBmpSize); 
    lpbitmap = (unsigned char *)GlobalLock(hDIB);  
	//get the actual bitmap 'bits'
	getdibitsresult = GetDIBits(compatiblescreendc, compatiblebitmap, 0,(UINT)finalbmp.bmHeight, lpbitmap, (BITMAPINFO *)&bminfoheader, DIB_RGB_COLORS);
	if(getdibitsresult == 0){
		outputerror(DBG_ERROR,"%s\n","takescreenshot::GetDIBits() Failed");
		ReleaseDC(NULL,screendc);
		DeleteDC(compatiblescreendc);
		DeleteObject(compatiblebitmap);
		SecureZeroMemory(lpbitmap,dwBmpSize);
		GlobalUnlock(hDIB); 
		return 1;
	}

    dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
    bmfileheader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER); 
    bmfileheader.bfSize = dwSizeofDIB; 
    bmfileheader.bfType = 0x4D42;	

	outputerror(DBG_INFO,"%s\n","takescreenshot::screenshot taken, preparing memory file");
	*screenshotbuffersize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwBmpSize;
	outputerror(DBG_INFO,"%s %i\n","takescreenshot::memfile size",*screenshotbuffersize);
	*screenshotbuffer = (unsigned char *)malloc(*screenshotbuffersize);
	if(screenshotbuffer == NULL){
		Sleep(10000);// 10 seconds
		*screenshotbuffer = (unsigned char *)malloc(*screenshotbuffersize);
		if(screenshotbuffer == NULL){
			outputerror(DBG_ERROR,"%s\n","takescreenshot::malloc() final file failed");
			ReleaseDC(NULL,screendc);
			DeleteDC(compatiblescreendc);
			DeleteObject(compatiblebitmap);
			SecureZeroMemory(lpbitmap,dwBmpSize);
			GlobalUnlock(hDIB);
			return 1;
		}
	}
	outputerror(DBG_INFO,"%s\n","takescreenshot::memfile prepared, copy bytes");
	/* create the full file in memory */
	memcpy_s(*screenshotbuffer,*screenshotbuffersize,&bmfileheader,sizeof(BITMAPFILEHEADER));
	outputerror(DBG_INFO,"%s\n","takescreenshot::memfile added bitmap file header");
	memcpy_s(*screenshotbuffer+sizeof(BITMAPFILEHEADER),*screenshotbuffersize,&bminfoheader,sizeof(BITMAPINFOHEADER));
	outputerror(DBG_INFO,"%s\n","takescreenshot::memfile added bitmap info header");
	memcpy_s(*screenshotbuffer+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER),*screenshotbuffersize,lpbitmap,dwBmpSize);
	outputerror(DBG_INFO,"%s\n","takescreenshot::memfile added bitmap content");		
	/* we could have used more of these in this app */
	SecureZeroMemory(lpbitmap,dwBmpSize);
	SecureZeroMemory(&bmfileheader,sizeof(BITMAPFILEHEADER));
	SecureZeroMemory(&bminfoheader,sizeof(BITMAPINFOHEADER));
	/*release resources*/
	GlobalUnlock(hDIB);
	ReleaseDC(NULL,screendc);
	DeleteDC(compatiblescreendc);
	DeleteObject(compatiblebitmap);
	GlobalFree(hDIB);
	outputerror(DBG_INFO,"%s\n","takescreenshot::done screenshot in memory");
	return 0;
}
示例#16
0
static fz_image *render_to_pixmap(fz_context *ctx, HBITMAP hbmp, SizeI size)
{
    int w = size.dx, h = size.dy;
    int stride = ((w * 3 + 3) / 4) * 4;

    unsigned char *data = (unsigned char *)fz_malloc(ctx, stride * h);

    BITMAPINFO bmi = { 0 };
    bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
    bmi.bmiHeader.biWidth = w;
    bmi.bmiHeader.biHeight = -h;
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biBitCount = 24;
    bmi.bmiHeader.biCompression = BI_RGB;

    HDC hDC = GetDC(nullptr);
    int res = GetDIBits(hDC, hbmp, 0, h, data, &bmi, DIB_RGB_COLORS);
    ReleaseDC(nullptr, hDC);
    if (!res) {
        fz_free(ctx, data);
        fz_throw(ctx, FZ_ERROR_GENERIC, "GetDIBits failed");
    }

    // convert BGR with padding to RGB without padding
    unsigned char *out = data;
    bool is_grayscale = true;
    for (int y = 0; y < h; y++) {
        const unsigned char *in = data + y * stride;
        unsigned char green, blue;
        for (int x = 0; x < w; x++) {
            is_grayscale = is_grayscale && in[0] == in[1] && in[0] == in[2];
            blue = *in++;
            green = *in++;
            *out++ = *in++;
            *out++ = green;
            *out++ = blue;
        }
    }
    // convert grayscale RGB to proper grayscale
    if (is_grayscale) {
        const unsigned char *in = out = data;
        for (int i = 0; i < w * h; i++) {
            *out++ = *in++;
            in += 2;
        }
    }

    fz_compressed_buffer *buf = nullptr;
    fz_var(buf);

    fz_try(ctx) {
        buf = fz_malloc_struct(ctx, fz_compressed_buffer);
        buf->buffer = fz_new_buffer(ctx, w * h * 4 + 10);
        buf->params.type = FZ_IMAGE_FLATE;
        buf->params.u.flate.predictor = 1;

        z_stream zstm = { 0 };
        zstm.next_in = data;
        zstm.avail_in = out - data;
        zstm.next_out = buf->buffer->data;
        zstm.avail_out = buf->buffer->cap;

        res = deflateInit(&zstm, 9);
        if (res != Z_OK)
            fz_throw(ctx, FZ_ERROR_GENERIC, "deflate failure %d", res);
        res = deflate(&zstm, Z_FINISH);
        if (res != Z_STREAM_END)
            fz_throw(ctx, FZ_ERROR_GENERIC, "deflate failure %d", res);
        buf->buffer->len = zstm.total_out;
        res = deflateEnd(&zstm);
        if (res != Z_OK)
            fz_throw(ctx, FZ_ERROR_GENERIC, "deflate failure %d", res);
    }
    fz_always(ctx) {
        fz_free(ctx, data);
    }
    fz_catch(ctx) {
        fz_free_compressed_buffer(ctx, buf);
        fz_rethrow(ctx);
    }

    fz_colorspace *cs = is_grayscale ? fz_device_gray(ctx) : fz_device_rgb(ctx);
    return fz_new_image(ctx, w, h, 8, cs, 96, 96, 0, 0, nullptr, nullptr, buf, nullptr);
}
示例#17
0
bool CxImageWMF::Decode(CxFile *hFile, long nForceWidth, long nForceHeight)
{
	if (hFile == NULL) return false;

	HENHMETAFILE	hMeta;
	HDC				hDC;
	int				cx,cy;

	//save the current position of the file
	long pos = hFile->Tell();

	// Read the Metafile and convert to an Enhanced Metafile
	METAFILEHEADER	mfh;
	hMeta = ConvertWmfFiletoEmf(hFile, &mfh);
	if (hMeta) {	// ok, it's a WMF

/////////////////////////////////////////////////////////////////////
//	We use the original WMF size information, because conversion to
//	EMF adjusts the Metafile to Full Screen or does not set rclBounds at all
//	ENHMETAHEADER	emh;
//	UINT			uRet;
//	uRet = GetEnhMetaFileHeader(hMeta,					// handle of enhanced metafile 
//								sizeof(ENHMETAHEADER),	// size of buffer, in bytes 
//								&emh); 					// address of buffer to receive data  
//	if (!uRet){
//		DeleteEnhMetaFile(hMeta);
//		return false;
//	}
//	// calculate size
//	cx = emh.rclBounds.right - emh.rclBounds.left;
//	cy = emh.rclBounds.bottom - emh.rclBounds.top;
/////////////////////////////////////////////////////////////////////

		// calculate size
		// scale the metafile (pixels/inch of metafile => pixels/inch of display)
		// mfh.inch already checked to be <> 0

		hDC = ::GetDC(0);
		int cx1 = ::GetDeviceCaps(hDC, LOGPIXELSX);
		int cy1 = ::GetDeviceCaps(hDC, LOGPIXELSY);
		::ReleaseDC(0, hDC);

		cx = (mfh.bbox.right - mfh.bbox.left) * cx1 / mfh.inch;
		cy = (mfh.bbox.bottom - mfh.bbox.top) * cy1 / mfh.inch;

	} else {		// maybe it's an EMF...

		hFile->Seek(pos,SEEK_SET);

		ENHMETAHEADER	emh;
		hMeta = ConvertEmfFiletoEmf(hFile, &emh);

		if (!hMeta){
			strcpy(info.szLastError,"corrupted WMF");
			return false; // definitively give up
		}
		// ok, it's an EMF
		// calculate size
		cx = emh.rclBounds.right - emh.rclBounds.left;
		cy = emh.rclBounds.bottom - emh.rclBounds.top;
	}

	if (info.nEscape) {	// Check if cancelled
		DeleteEnhMetaFile(hMeta);
		strcpy(info.szLastError,"Cancelled");
		return false;
	}

	if (!cx || !cy)	{
		DeleteEnhMetaFile(hMeta);
		strcpy(info.szLastError,"empty WMF");
		return false;
	}

	if (nForceWidth) cx=nForceWidth;
	if (nForceHeight) cy=nForceHeight;
	ShrinkMetafile(cx, cy);		// !! Otherwise Bitmap may have bombastic size

	HDC hDC0 = GetDC(0);	// DC of screen
	HBITMAP hBitmap = CreateCompatibleBitmap(hDC0, cx, cy);	// has # colors of display
	hDC = CreateCompatibleDC(hDC0);	// memory dc compatible with screen
	ReleaseDC(0, hDC0);	// don't need anymore. get rid of it.

	if (hDC){
		if (hBitmap){
			RECT rc = {0,0,cx,cy};
			int bpp = ::GetDeviceCaps(hDC, BITSPIXEL);

			HBITMAP hBitmapOld = (HBITMAP)SelectObject(hDC, hBitmap);

			// clear out the entire bitmap with windows background
			// because the MetaFile may not contain background information
			DWORD	dwBack = XMF_COLOR_BACK;
#if XMF_SUPPORT_TRANSPARENCY
			if (bpp == 24) dwBack = XMF_COLOR_TRANSPARENT;
#endif
		    DWORD OldColor = SetBkColor(hDC, dwBack);
		    ExtTextOut(hDC, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
			SetBkColor(hDC, OldColor);

			//retrieves optional palette entries from the specified enhanced metafile
			PLOGPALETTE plogPal;
			PBYTE pjTmp; 
			HPALETTE hPal; 
			int iEntries = GetEnhMetaFilePaletteEntries(hMeta, 0, NULL);
			if (iEntries) { 
				if ((plogPal = (PLOGPALETTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, 
					sizeof(DWORD) + sizeof(PALETTEENTRY)*iEntries )) == NULL) { 
					DeleteObject(hBitmap);
					DeleteDC(hDC);
					DeleteEnhMetaFile(hMeta);
					strcpy(info.szLastError,"Cancelled");
					return false;
				} 

				plogPal->palVersion = 0x300; 
				plogPal->palNumEntries = (WORD) iEntries; 
				pjTmp = (PBYTE) plogPal; 
				pjTmp += 4; 

				GetEnhMetaFilePaletteEntries(hMeta, iEntries, (PPALETTEENTRY)pjTmp); 
				hPal = CreatePalette(plogPal); 
				GlobalFree(plogPal); 

				SelectPalette(hDC, hPal, FALSE); 
				RealizePalette(hDC); 
			} 
			
			// Play the Metafile into Memory DC
			BOOL bRet = PlayEnhMetaFile(hDC,	// handle to a device context 
									hMeta,	// handle to an enhanced metafile  
									&rc); 	// pointer to bounding rectangle

			SelectObject(hDC, hBitmapOld);
			DeleteEnhMetaFile(hMeta);	// we are done with this one

			if (info.nEscape) {	// Check if cancelled
				DeleteObject(hBitmap);
				DeleteDC(hDC);
				strcpy(info.szLastError,"Cancelled");
				return false;
			}

			// the Bitmap now has the image.
			// Create our DIB and convert the DDB into DIB
			if (!Create(cx, cy, bpp, CXIMAGE_FORMAT_WMF)) {
				DeleteObject(hBitmap);
				DeleteDC(hDC);
				return false;
			}

#if XMF_SUPPORT_TRANSPARENCY
			if (bpp == 24) {
				RGBQUAD	rgbTrans = { XMF_RGBQUAD_TRANSPARENT };
				SetTransColor(rgbTrans);
			}
#endif
		    // We're finally ready to get the DIB. Call the driver and let
		    // it party on our bitmap. It will fill in the color table,
		    // and bitmap bits of our global memory block.
			bRet = GetDIBits(hDC, hBitmap, 0,
			        (UINT)cy, GetBits(), (LPBITMAPINFO)pDib, DIB_RGB_COLORS);

			DeleteObject(hBitmap);
			DeleteDC(hDC);

			return (bRet!=0);
		} else {
			DeleteDC(hDC);
		}
	} else {
		if (hBitmap) DeleteObject(hBitmap);
	}

	DeleteEnhMetaFile(hMeta);

	return false;
}
示例#18
0
BOOL CreateBMPFile(const char *szFile, HBITMAP hBMP) 
{
	// Saves the hBitmap as a bitmap.
	HDC					hdcScreen = CreateDC("DISPLAY", NULL, NULL, NULL); 
	HDC					hdcCompatible = CreateCompatibleDC(hdcScreen); 
	PBITMAPINFO			pbmi=NULL;
	BOOL				bret=FALSE;
	HANDLE				hf=NULL; // file handle
	BITMAPFILEHEADER	hdr; // bitmap file-header
	PBITMAPINFOHEADER	pbih=NULL; // bitmap info-header
	LPBYTE				lpBits=NULL; // memory pointer
	DWORD				dwTotal=0; // total count of bytes
	DWORD				cb=0; // incremental count of bytes
	BYTE				*hp=NULL; // byte pointer
	DWORD				dwTmp=0;
	BITMAP				bmp;

	memset(&bmp,0,sizeof(BITMAP));
	GetObject(hBMP,sizeof(BITMAP),&bmp);
	memset(&hdr,0,sizeof(hdr));
	{
		int cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel);
		if (cClrBits>8) {
			// No Palette (normally)
			pbmi = (PBITMAPINFO) calloc(1, sizeof(BITMAPINFOHEADER));
		}
		else {
			pbmi = (PBITMAPINFO) calloc(1, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (1<<(min(8,cClrBits))));
			pbmi->bmiHeader.biClrUsed = (1<<cClrBits);
		}

		// Initialize the fields in the BITMAPINFO structure.
		pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);

		// Retrieve the color table (RGBQUAD array) and the bits
		// (array of palette indices) from the DIB.
		if (!GetDIBits(hdcCompatible, hBMP, 0, bmp.bmHeight, NULL, pbmi, DIB_RGB_COLORS)) {
			goto to_return;
		}
	}
	pbih = &(pbmi->bmiHeader);
	pbmi->bmiHeader.biCompression=BI_RGB;
	lpBits = (LPBYTE) calloc(1, pbih->biSizeImage);

	if (!lpBits) { goto to_return; }

	if (!GetDIBits(hdcCompatible, hBMP, 0, (WORD) pbih->biHeight, lpBits, pbmi, DIB_RGB_COLORS)) {
		goto to_return;
	}

	// Create the .BMP file.
	hf = CreateFile(szFile, GENERIC_READ | GENERIC_WRITE, (DWORD) 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL);
	if (hf == INVALID_HANDLE_VALUE) {
		goto to_return;
	}
	hdr.bfType = 0x4d42; // 0x42 = "B" 0x4d = "M"
	// Compute the size of the entire file.
	hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) + pbih->biSize + pbih->biClrUsed*sizeof(RGBQUAD) + pbih->biSizeImage);
	hdr.bfReserved1 = 0;
	hdr.bfReserved2 = 0;

	// Compute the offset to the array of color indices.
	hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + pbih->biSize + pbih->biClrUsed*sizeof (RGBQUAD);

	// Copy the BITMAPFILEHEADER into the .BMP file.
	if (!WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER),	(LPDWORD) &dwTmp, NULL)) {
		goto to_return;
	}

	// Copy the BITMAPINFOHEADER and RGBQUAD array into the file.
	if (!WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER) + pbih->biClrUsed * sizeof (RGBQUAD), (LPDWORD) &dwTmp, ( NULL))) {
		goto to_return;
	}

	// Copy the array of color indices into the .BMP file.
	dwTotal = cb = pbih->biSizeImage;
	hp = lpBits;
	if (!WriteFile(hf, (LPSTR) hp, (int) cb, (LPDWORD) &dwTmp,NULL)) { goto to_return; }

	// Close the .BMP file.
	if (!CloseHandle(hf)) { goto to_return; }
	bret=TRUE;


	to_return:;
	// Free memory.
	if(pbmi)free(pbmi);
	if(lpBits)free(lpBits);
	DeleteDC(hdcCompatible);
	DeleteDC(hdcScreen);

	return bret;
}
示例#19
0
bool CFont::Init()
{
  HDC hDC = CreateCompatibleDC(0);
  int iXdpi, iYdpi;
  iXdpi = GetDeviceCaps(hDC, LOGPIXELSX);
  iYdpi = GetDeviceCaps(hDC, LOGPIXELSY);

  LOGFONT lf;
  lf.lfHeight = m_iSizePt * iYdpi / 72;
  lf.lfWidth = 0;
  lf.lfEscapement = 0;
  lf.lfOrientation = 0;
  lf.lfWeight = FW_DONTCARE;
  lf.lfItalic = false;
  lf.lfUnderline = false;
  lf.lfStrikeOut = false;
  lf.lfCharSet = ANSI_CHARSET;
  lf.lfOutPrecision = OUT_TT_PRECIS;
  lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  lf.lfQuality = ANTIALIASED_QUALITY;
  lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
  strcpy(lf.lfFaceName, m_sTypeface.m_pBuf);

  HFONT hFont = CreateFontIndirect(&lf);
  SelectObject(hDC, hFont);

  TEXTMETRIC tm;
  bool bRes;
  bRes = !!GetTextMetrics(hDC, &tm);
  m_iAscent = tm.tmAscent;
  m_iDescent = tm.tmDescent;
  m_iHeight = tm.tmHeight;
  m_iInternalLead = tm.tmInternalLeading;
  m_iExternalLead = tm.tmExternalLeading;
  m_iAverageWidth = tm.tmAveCharWidth;
//  m_iMaxWidth = tm.tmMaxCharWidth;
  m_iFirstChar = tm.tmFirstChar;

  int iChars = tm.tmLastChar - tm.tmFirstChar + 1;
  float fCols, fRows;

  ABC abc[MAX_CHARS];
  bRes = !!GetCharABCWidths(hDC, tm.tmFirstChar, tm.tmLastChar, abc + tm.tmFirstChar);

  int i;
  m_iMaxWidth = 0;
  for (i = 0; i < tm.tmFirstChar; i++)
    m_Chars[i].ch = 0;
  while (i <= tm.tmLastChar) {
    m_Chars[i].ch = i;
    m_Chars[i].iA = abc[i].abcA;
    m_Chars[i].iB = abc[i].abcB;
    m_Chars[i].iC = abc[i].abcC;
    m_iMaxWidth = Util::Max(m_iMaxWidth, m_Chars[i].iB);
    i++;
  }
  while (i < MAX_CHARS) {
    m_Chars[i].ch = 0;
    i++;
  }

  int iKernPairs;
  KERNINGPAIR *pKernPairs;
  iKernPairs = GetKerningPairs(hDC, 0, 0);
  pKernPairs = new KERNINGPAIR[iKernPairs];
  GetKerningPairs(hDC, iKernPairs, pKernPairs);

  for (i = 0; i < iKernPairs; i++) 
    m_KerningPairs.Add(TKerningPair((char) pKernPairs[i].wFirst, (char) pKernPairs[i].wSecond, pKernPairs[i].iKernAmount));

  delete [] pKernPairs;

  fRows = sqrt(iChars * m_iMaxWidth / (float) m_iHeight);
  fCols = fRows * m_iHeight / (float) m_iMaxWidth;
  m_iCellCols = (int) ceil(fCols);
  m_iCellRows = (int) ceil(fRows);

  if (m_iCellCols > m_iCellRows) {
    if (m_iCellCols * (m_iCellRows - 1) >= iChars)
      m_iCellRows--;
  } else
    if ((m_iCellCols - 1) * m_iCellRows >= iChars) 
      m_iCellCols--;

  ASSERT(m_iCellRows * m_iCellCols >= iChars);

  BITMAPINFO bmi;
  bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
  bmi.bmiHeader.biWidth = m_iCellCols * m_iMaxWidth; 
  bmi.bmiHeader.biHeight = -m_iCellRows * m_iHeight; 
  bmi.bmiHeader.biPlanes = 1; 
  bmi.bmiHeader.biBitCount = 24; 
  bmi.bmiHeader.biCompression = BI_RGB; 
  bmi.bmiHeader.biSizeImage = 0; 
  bmi.bmiHeader.biXPelsPerMeter = (int) (iXdpi / 2.54f * 100); 
  bmi.bmiHeader.biYPelsPerMeter = (int) (iYdpi / 2.54f * 100); 
  bmi.bmiHeader.biClrUsed = 0; 
  bmi.bmiHeader.biClrImportant = 0; 

  HBITMAP hBmp = CreateDIBSection(hDC, &bmi, 0, 0, 0, 0);
  SelectObject(hDC, hBmp);

  HBRUSH hBrush = CreateSolidBrush(RGB(0, 0, 0)); 
  SelectObject(hDC, hBrush);

  Rectangle(hDC, 0, 0, m_iCellCols * m_iMaxWidth, m_iCellRows * m_iHeight);

  SetTextColor(hDC, RGB(255, 255, 255));
  SetBkColor(hDC, RGB(0, 0, 0));
  SetBkMode(hDC, TRANSPARENT);
  SetTextAlign(hDC, TA_TOP | TA_LEFT | TA_NOUPDATECP);

  for (int iRow = 0; iRow < m_iCellRows; iRow++)
    for (int iCol = 0; iCol < m_iCellCols; iCol++) {
      RECT rc;
      char chBuf[2] = { m_iFirstChar + iRow * m_iCellCols + iCol, 0 };
      if (!m_Chars[(uint8_t) chBuf[0]].ch)
        continue;
      rc.left = iCol * m_iMaxWidth - m_Chars[(uint8_t) chBuf[0]].iA;
      rc.top = iRow * m_iHeight;
      rc.right = rc.left + m_iMaxWidth;
      rc.bottom = rc.top + m_iHeight;
//      DrawText(hDC, chBuf, 1, &rc, DT_LEFT | DT_TOP);
      TextOut(hDC, rc.left, rc.top, chBuf, 1);
    }

  bRes = !!GdiFlush();

  bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
  bmi.bmiHeader.biWidth = m_iCellCols * m_iMaxWidth; 
  bmi.bmiHeader.biHeight = -m_iCellRows * m_iHeight; 
  bmi.bmiHeader.biPlanes = 1; 
  bmi.bmiHeader.biBitCount = 32; 
  bmi.bmiHeader.biCompression = BI_RGB; 
  bmi.bmiHeader.biSizeImage = 0; 
  bmi.bmiHeader.biXPelsPerMeter = (int) (iXdpi / 2.54f * 100); 
  bmi.bmiHeader.biYPelsPerMeter = (int) (iYdpi / 2.54f * 100); 
  bmi.bmiHeader.biClrUsed = 0; 
  bmi.bmiHeader.biClrImportant = 0; 
  int iSize = bmi.bmiHeader.biWidth * abs(bmi.bmiHeader.biHeight) * bmi.bmiHeader.biBitCount / 8;
  uint8_t *pBuf = new uint8_t[iSize];
  bRes = !!GetDIBits(hDC, hBmp, 0, abs(bmi.bmiHeader.biHeight), pBuf, &bmi, DIB_RGB_COLORS);

  for (i = 0; i < iSize; i += 4)
//    Util::Swap(pBuf[i], pBuf[i + 2]);
    pBuf[i / 4] = pBuf[i];

  m_pTexture = new CTexture();
  bRes = m_pTexture->Init(bmi.bmiHeader.biWidth, abs(bmi.bmiHeader.biHeight), DXGI_FORMAT_R8_UNORM, 1, pBuf, bmi.bmiHeader.biWidth /* * bmi.bmiHeader.biBitCount / 8*/, 0);

/*
  ID3D11Resource *pTexRes = 0;
  m_pTexture->m_pTextureView->GetResource(&pTexRes);
  D3DX11SaveTextureToFile(CGraphics::Get()->m_pDeviceContext, pTexRes, D3DX11_IFF_BMP, "font.bmp");
  SAFE_RELEASE(pTexRes);
*/

  delete [] pBuf;
  DeleteObject(hBrush);
  DeleteObject(hBmp);
  DeleteObject(hFont);
  DeleteDC(hDC);

  if (!InitModel())
    return false;

  return true;
}
示例#20
0
文件: clipbrd.c 项目: mingpen/OpenNT
VOID
DoPaste(
    IN PCONSOLE_INFORMATION Console
    )

/*++

  Perform paste request into old app by sucking out clipboard
        contents and writing them to the console's input buffer

--*/

{
    BOOL Success;
    HANDLE ClipboardDataHandle;

    if (Console->Flags & CONSOLE_SCROLLING) {
        return;
    }

    //
    // Get paste data from clipboard
    //

    Success = OpenClipboard(Console->hWnd);
    if (!Success)
        return;

    if (Console->CurrentScreenBuffer->Flags & CONSOLE_TEXTMODE_BUFFER) {
        PWCHAR pwstr;

        ClipboardDataHandle = GetClipboardData(CF_UNICODETEXT);
        if (ClipboardDataHandle == NULL) {
            CloseClipboard();   // Close clipboard
            return;
        }
        pwstr = GlobalLock(ClipboardDataHandle);
        DoStringPaste(Console,pwstr,GlobalSize(ClipboardDataHandle));
        GlobalUnlock(ClipboardDataHandle);

    } else {
        HBITMAP hBitmapSource,hBitmapTarget;
        HDC hDCMemSource,hDCMemTarget;
        BITMAP bm;
        PSCREEN_INFORMATION ScreenInfo;

        hBitmapSource = GetClipboardData(CF_BITMAP);
        if (hBitmapSource) {

            ScreenInfo = Console->CurrentScreenBuffer;
            NtWaitForSingleObject(ScreenInfo->BufferInfo.GraphicsInfo.hMutex,
                                  FALSE, NULL);

            hBitmapTarget = CreateDIBitmap(ScreenInfo->Console->hDC,
                                     &ScreenInfo->BufferInfo.GraphicsInfo.lpBitMapInfo->bmiHeader,
                                     CBM_INIT,
                                     ScreenInfo->BufferInfo.GraphicsInfo.BitMap,
                                     ScreenInfo->BufferInfo.GraphicsInfo.lpBitMapInfo,
                                     ScreenInfo->BufferInfo.GraphicsInfo.dwUsage
                                    );
            if (hBitmapTarget) {
                hDCMemTarget = CreateCompatibleDC ( Console->hDC );
                hDCMemSource = CreateCompatibleDC ( Console->hDC );
                SelectObject( hDCMemTarget, hBitmapTarget );
                SelectObject( hDCMemSource, hBitmapSource );
                GetObjectW(hBitmapSource, sizeof (BITMAP), (LPSTR) &bm);
                BitBlt ( hDCMemTarget, 0, 0, bm.bmWidth, bm.bmHeight,
                     hDCMemSource, 0, 0, SRCCOPY);
                GetObjectW(hBitmapTarget, sizeof (BITMAP), (LPSTR) &bm);

                // copy the bits from the DC to memory

                GetDIBits(hDCMemTarget, hBitmapTarget, 0, bm.bmHeight,
                          ScreenInfo->BufferInfo.GraphicsInfo.BitMap,
                          ScreenInfo->BufferInfo.GraphicsInfo.lpBitMapInfo,
                          ScreenInfo->BufferInfo.GraphicsInfo.dwUsage);
                DeleteDC(hDCMemSource);
                DeleteDC(hDCMemTarget);
                DeleteObject(hBitmapTarget);
                InvalidateRect(Console->hWnd,NULL,FALSE); // force repaint
            }
            NtReleaseMutant(ScreenInfo->BufferInfo.GraphicsInfo.hMutex, NULL);
        }
    }
    CloseClipboard();
    return;
}
示例#21
0
文件: dev.c 项目: Absolight/Prima
void
image_query_bits( Handle self, Bool forceNewImage)
{
   PImage i = ( PImage) self;
   XBITMAPINFO xbi;
   BITMAPINFO * bi;
   int  newBits;
   HDC  ops = nil;
   BITMAP bitmap;

   if ( forceNewImage) {
      ops = sys ps;
      if ( !ops) {
         if ( !( sys ps = dc_alloc())) return;
      }
   }

   if ( !GetObject( sys bm, sizeof( BITMAP), ( LPSTR) &bitmap)) {
      apiErr;
      return;
      // if GetObject fails to get even BITMAP, there will be no good in farther run for sure.
   }

   if (( bitmap. bmPlanes == 1) && (
          ( bitmap. bmBitsPixel == 1) ||
          ( bitmap. bmBitsPixel == 4) ||
          ( bitmap. bmBitsPixel == 8) ||
          ( bitmap. bmBitsPixel == 24)
      ))
      newBits = bitmap. bmBitsPixel;
   else {
      newBits = ( bitmap. bmBitsPixel <= 4) ? 4 :
                (( bitmap. bmBitsPixel <= 8) ? 8 : 24);
   }


   if ( forceNewImage) {
      i-> self-> create_empty( self, bitmap. bmWidth, bitmap. bmHeight, newBits);
   } else {
      if (( newBits != ( i-> type & imBPP)) || (( i-> type & ~imBPP) != 0))
         i-> self-> create_empty( self, i-> w, i-> h, newBits);
   }

   bi = image_get_binfo( self, &xbi);

   if ( !GetDIBits( sys ps, sys bm, 0, i-> h, i-> data, bi, DIB_RGB_COLORS)) apiErr;

   if (( i-> type & imBPP) < 24) {
      int j, nColors = 1 << ( i-> type & imBPP);
      for ( j = 0; j < nColors; j++) {
         i-> palette[ j]. r = xbi. bmiColors[ j]. rgbRed;
         i-> palette[ j]. g = xbi. bmiColors[ j]. rgbGreen;
         i-> palette[ j]. b = xbi. bmiColors[ j]. rgbBlue;
      }
   }

   if ( forceNewImage) {
      if ( !ops) {
         dc_free();
      }
      sys ps = ops;
   }
}
示例#22
0
/*******************************************************************************
// extracts the dimensional information, pixel array, and color table from an
// HBITMAP.
// hBitmap can be a handle to a DIB or a DDB.  This function assumes that DDBs
// will not have a palette.  If you create a DDB on a 256-color graphics card,
// then the DDB will have a palette and this function will fail.
//
// returns BMK_OK if successfull, and error state otherwise.
********************************************************************************/
BMGError GetDataFromBitmap( HBITMAP hBitmap,
                            struct BMGImageStruct *img,
                            int remove_alpha )
{
    unsigned int        DIBScanWidth;
    DIBSECTION          DS;
    HWND                hWnd = GetForegroundWindow();
    HDC                 hDC = NULL;
    HDC                 hMemDC = NULL;
    unsigned char       red, green, blue;
    int                 FreelpBits = 0;
    unsigned int        numBytes;
    size_t              soDIBSECTION = sizeof(DIBSECTION);
    size_t              soBITMAP = sizeof(BITMAP);

    unsigned char *p, *q, *lpBits, alpha;

    jmp_buf err_jmp;
    int error;
    BMGError bmgerr;

    /* error handler */
    error = setjmp( err_jmp );
    if ( error != 0 )
    {
        if ( hMemDC != NULL )
            DeleteDC( hMemDC );
        if ( hDC != NULL )
            ReleaseDC( hWnd, hDC );
        if ( FreelpBits )
            free( lpBits );
        FreeBMGImage( img );
        SetLastBMGError( (BMGError)error );
        return (BMGError)error;
    }

    SetLastBMGError( BMG_OK );
    /* check for valid bitmap*/
    if ( !hBitmap )
        longjmp( err_jmp, (int)errInvalidBitmapHandle );

    /* Extract DIBSECTION info from the HBITMAP.  numBytes will equal
    // soDIBSECTION (84) if hBitmap is a handle to a DIBSECTION (DIB).
    // numBytes will equal soBITMAP (24) if hBitmap is a handle to a
    // BITMAP (DDB). */
    numBytes = GetObject( hBitmap, sizeof(DIBSECTION), &DS );
    if ( numBytes == 0 )
        longjmp( err_jmp, (int)errWindowsAPI );

    img->opt_for_bmp = 1;
    if ( numBytes == soDIBSECTION )
    {
        img->width = DS.dsBmih.biWidth;
        img->height = DS.dsBmih.biHeight;
        img->bits_per_pixel = (unsigned char)DS.dsBmih.biBitCount;
        if ( img->bits_per_pixel <= 8 && DS.dsBmih.biClrUsed > 0 )
            img->palette_size = (unsigned short)DS.dsBmih.biClrUsed;
        lpBits = (unsigned char *)DS.dsBm.bmBits;
    }
    /* this may be a DDB which must be handled differently */
    else if ( numBytes == soBITMAP )
    {
        BITMAP bm;
        BITMAPINFO bmi;

        if ( GetObject( hBitmap, sizeof(BITMAP), &bm ) == 0 )
            longjmp( err_jmp, (int)errWindowsAPI );

        /* DDB with a palette */
        if ( bm.bmBitsPixel <= 8 )
            longjmp( err_jmp, (int)errInvalidPixelFormat );

        img->width = bm.bmWidth;
        img->height = bm.bmHeight;
        img->bits_per_pixel = (unsigned char)bm.bmBitsPixel;
        bmi = InternalCreateBMI( bm.bmWidth, bm.bmHeight, bm.bmBitsPixel,
                                 BI_RGB );

        lpBits = (unsigned char *)calloc( bm.bmHeight * bm.bmWidthBytes,
                                          sizeof(unsigned char) );
        if ( lpBits == 0 )
            longjmp( err_jmp, (int)errMemoryAllocation );
        FreelpBits = 1;
        hDC = GetDC( hWnd );
        if ( GetDIBits(hDC, hBitmap, 0, bm.bmHeight, (void *)lpBits, &bmi,
                       DIB_RGB_COLORS ) == 0 )
            longjmp( err_jmp, (int)errWindowsAPI );
        ReleaseDC( hWnd, hDC );
        hDC = NULL;
    }
    else /* I have no idea what this is */
        longjmp( err_jmp, (int)errInvalidBitmapHandle );

    /* allocate memory */
    bmgerr = AllocateBMGImage( img );
    if ( bmgerr != BMG_OK )
        longjmp( err_jmp, (int)bmgerr );

    /* dimensions */
    DIBScanWidth = ( img->width * img->bits_per_pixel + 7 )/8;
    if ( DIBScanWidth % 4 )
        DIBScanWidth += 4 - DIBScanWidth % 4;

    p = img->bits;
    for ( q = lpBits; q < lpBits + DIBScanWidth * img->height;
            p += img->scan_width, q += DIBScanWidth )
    {
        memcpy( (void *)p, (void *)q, DIBScanWidth );
    }

    /* "un-blend" the image if requested.  NOTE: unblending only works with
    // bland backgrounds */
    if ( remove_alpha > 0 &&
         img->bits_per_pixel == 32 &&
         numBytes == soDIBSECTION )
    {
        unsigned char *color = GetBackgroundColor();
        red   = color[2];
        green = color[1];
        blue  = color[0];

        for ( p = img->bits; p < img->bits + img->scan_width * img->height;
              p += 4 )
        {
            alpha = p[3];
            p[2] = InverseAlphaComp( p[2], alpha, blue);
            p[1] = InverseAlphaComp( p[1], alpha, green);
            p[0] = InverseAlphaComp( p[0], alpha, red);
        }
    }

    /* 32-bit DDBs must have the alpha channel set to 0xFF before they are
    // saved to a file. This may not be true for all devices that generate
    // 32-bit DDBs.  I have only created 32-bit DDBs using an Intense3D Wildcat
    // 4110 card.  The alpha channel was always 0. */
    if (img->bits_per_pixel == 32 && numBytes == soBITMAP )
    {
        for ( p = img->bits + 3; p < img->bits + img->scan_width * img->height;
                                 p += 4 )
        {
            *p = 0xFF;
        }
    }

    /* create palette if necessary */
    if ( img->bits_per_pixel <= 8 )
    {
        hDC = GetDC( hWnd );
        hMemDC = CreateCompatibleDC( hDC );
        SelectObject( hMemDC, hBitmap );
        if ( !GetDIBColorTable( hMemDC, 0, img->palette_size,
                                (RGBQUAD *)img->palette ) )
        {
            longjmp( err_jmp, (int)errWindowsAPI );
        }
        DeleteDC( hMemDC );
        ReleaseDC( hWnd, hDC );
    }

    if ( FreelpBits )
        free( lpBits );

    return BMG_OK;
}
示例#23
0
BOOL CDib::Open(HWND hWnd, const char *pFileName, BOOL bOpenFromFile)
{
	/*
	UINT fuLoad;

	if(bOpenFromFile==TRUE)
		fuLoad = LR_CREATEDIBSECTION|LR_LOADFROMFILE|LR_DEFAULTSIZE;
	else
		fuLoad = (bOpenFromFile?LR_CREATEDIBSECTION:0)|LR_LOADFROMFILE|LR_DEFAULTSIZE;
	*/
	m_hBitmap=(HBITMAP)::LoadImage(
		bOpenFromFile? NULL : (HINSTANCE)GetWindowLong(hWnd,GWL_HINSTANCE),
		pFileName,
		IMAGE_BITMAP,
		0,0,
		//fuLoad);
		LR_CREATEDIBSECTION|(bOpenFromFile?LR_LOADFROMFILE:0)|LR_DEFAULTSIZE);
	if(m_hBitmap==NULL){
//		SetErrors(CMERR_CANT_OPEN_FILE,pFileName);
		return FALSE;
	}

	BITMAP bm;
	BITMAPINFOHEADER bi;
	LPBITMAPINFOHEADER lpbi;	// 24bit라서 팔레트 정보가 없을 것이므로 필요없으나... 확장을 위해

	GetObject(m_hBitmap,sizeof(BITMAP),&bm);

	if(bm.bmHeight>=0)m_bTopDown=FALSE;
	else m_bTopDown=TRUE;

    bi.biSize				= sizeof(BITMAPINFOHEADER);
    bi.biWidth				= bm.bmWidth;
    bi.biHeight				= bm.bmHeight;
    bi.biPlanes				= 1;
    //bi.biBitCount           = bm.bmPlanes * bm.bmBitsPixel;
	bi.biBitCount			= 24;			// 8bit 도 24bit로 읽어낸다. 따라서 Pal 정보가 없다.
    bi.biCompression		= BI_RGB;
    bi.biSizeImage			= 0;
    bi.biXPelsPerMeter		= 0;
    bi.biYPelsPerMeter		= 0;
    bi.biClrUsed			= 0;
    bi.biClrImportant		= 0;

// 팔레트 개수
#define DibNumColors(lpbi)	((lpbi)->biClrUsed == 0 && (lpbi)->biBitCount <= 8 \
								? (WORD)(1 << (int)(lpbi)->biBitCount) \
								: (WORD)(lpbi)->biClrUsed)

	// BITMAPINFO( BITMAPINFOHEADER+PAL ) 의 크기
	DWORD nLen  = bi.biSize + DibNumColors(&bi) * sizeof(RGBQUAD);

	lpbi=(LPBITMAPINFOHEADER)new char[nLen];

	*lpbi=bi;

	HDC hDC=GetDC(hWnd);
	GetDIBits(hDC,m_hBitmap,0,bi.biHeight,NULL,(LPBITMAPINFO)lpbi,DIB_RGB_COLORS);
	ReleaseDC(hWnd,hDC);

	bi=*lpbi;

	// 드라이버가 biSizeImage를 채우지 않는 경우
	if(bi.biSizeImage==0){
		bi.biSizeImage=(DWORD)WIDTHBYTES(bm.bmWidth*bi.biBitCount)*bm.bmHeight;
		if(bi.biCompression!=BI_RGB)
			bi.biSizeImage=(bi.biSizeImage*3)/2;
	}

	delete[] lpbi;

	nLen=bi.biSize+DibNumColors(&bi)*sizeof(RGBQUAD)+bi.biSizeImage;

	//lpbi=(LPBITMAPINFOHEADER)new char[nLen];
	m_pBitmapData=new BYTE[nLen];

	if(m_pBitmapData==NULL){
		//_RPT0(_CRT_WARN,"Memory Allocation Error");
//		SetError(CMERR_OUT_OF_MEMORY);
		return FALSE;
	}

	*(LPBITMAPINFOHEADER)m_pBitmapData=bi;

	hDC=GetDC(hWnd);
	GetDIBits(hDC,m_hBitmap,0,bi.biHeight,DibPtr((LPBITMAPINFOHEADER)m_pBitmapData),(LPBITMAPINFO)m_pBitmapData,DIB_RGB_COLORS);
	ReleaseDC(hWnd,hDC);
	
	return TRUE;
}
示例#24
0
VOID
AdjustBrightness(HBITMAP hOrigBitmap,
                 HBITMAP hNewBitmap,
                 HWND hwnd,
                 HDC hdcMem,
                 INT RedVal,
                 INT GreenVal,
                 INT BlueVal)
{
    BITMAPINFO bi;
    BITMAP bitmap;
    BOOL bRes;
    DWORD Count = 0;
    INT i, j;
    PBYTE pBits;
    RECT rc;

    GetObject(hNewBitmap,
              sizeof(BITMAP),
              &bitmap);

    /* Bitmap header */
    bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
    bi.bmiHeader.biWidth = bitmap.bmWidth;
    bi.bmiHeader.biHeight = bitmap.bmHeight;
    bi.bmiHeader.biPlanes = 1;
    bi.bmiHeader.biBitCount = 32;
    bi.bmiHeader.biCompression = BI_RGB;
    bi.bmiHeader.biSizeImage = bitmap.bmWidth * bitmap.bmHeight * 4;
    bi.bmiHeader.biClrUsed = 0;
    bi.bmiHeader.biClrImportant = 0;

    /* Buffer */
    pBits = (PBYTE)HeapAlloc(ProcessHeap,
                             0,
                             bitmap.bmWidth * bitmap.bmHeight * 4);
    if (!pBits)
        return;

    /* get the bits from the original bitmap */
    bRes = GetDIBits(hdcMem,
                     hOrigBitmap,
                     0,
                     bitmap.bmHeight,
                     pBits,
                     &bi,
                     DIB_RGB_COLORS);

    for (i = 0; i < bitmap.bmHeight; i++)
    {
        for (j = 0; j < bitmap.bmWidth; j++)
        {
            DWORD Val = 0;
            INT b, g, r;

            CopyMemory(&Val,
                       &pBits[Count],
                       4);

            /* Get pixels in reverse order */
            b = GetRValue(Val);
            g = GetGValue(Val);
            r = GetBValue(Val);

            /* Red */
            r += RedVal;
            if (r > 255) r = 255;
            else if (r < 0) r = 0;

            /* Green */
            g += GreenVal;
            if (g > 255) g = 255;
            else if (g < 0) g = 0;

            /* Blue */
            b += BlueVal;
            if (b > 255) b = 255;
            else if (b < 0) b = 0;

            /* Store in reverse order */
            Val = RGB(b, g, r);
            CopyMemory(&pBits[Count],
                       &Val,
                       4);

            /* RGB color take 4 bytes.The high-order byte must be zero */
            Count += 4;
        }
    }

    /* Set the new pixel bits */
    SetDIBits(hdcMem,
              hNewBitmap,
              0,
              bRes,
              pBits,
              &bi,
              DIB_RGB_COLORS);

    HeapFree(ProcessHeap,
             0,
             pBits);

    GetClientRect(hwnd,
                  &rc);

    InvalidateRect(hwnd,
                   &rc,
                   FALSE);
}
示例#25
0
文件: console.c 项目: Art17/Courses
int Console_showCinema (Console* c)
{
    int status = 0;

    const int n = 256;
    char szFileName[n];
    strcpy (szFileName, "cinema.bmp");

    HBITMAP hBmp;
    BITMAP bmp;

    hBmp = (HBITMAP)LoadImage (NULL, szFileName, IMAGE_BITMAP, NULL, NULL, LR_LOADFROMFILE);

    if (hBmp == NULL)
    {
        status = 2;
        ErrorModule_setLastError(status);
        return status;
    }

    GetObject (hBmp, sizeof (BITMAP), &bmp);

    int BitCount = bmp.bmPlanes*bmp.bmBitsPixel;
    int colorSize = 0;

    switch (BitCount)
    {
           case 1:
           case 4:
           case 8:
           case 32:
                colorSize = sizeof (RGBQUAD)* (1 << BitCount);
                break;
           case 16:
           case 24:
                colorSize = NULL;
                break;
           }

    int dataSize = bmp.bmWidthBytes*bmp.bmHeight;

    void* pvBits = malloc (dataSize);

    BITMAPINFO* pBmi = (BITMAPINFO*)malloc(sizeof (BITMAPINFOHEADER) + colorSize);

    pBmi->bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
    pBmi->bmiHeader.biWidth = bmp.bmWidth;
    pBmi->bmiHeader.biHeight = -bmp.bmHeight;
    pBmi->bmiHeader.biPlanes = 1;
    pBmi->bmiHeader.biBitCount = BitCount;
    pBmi->bmiHeader.biCompression = BI_RGB;
    pBmi->bmiHeader.biSizeImage = dataSize;
    pBmi->bmiHeader.biXPelsPerMeter = pBmi->bmiHeader.biYPelsPerMeter = 0;
    pBmi->bmiHeader.biClrImportant = 0;

    HDC hDC = GetDC (0);
    GetDIBits (hDC, hBmp, 0, bmp.bmHeight, pvBits, pBmi, DIB_RGB_COLORS);
    ReleaseDC (0, hDC);

    COORD pos;
    for (int y = 0; y < bmp.bmHeight; y++)
    {
    	for (int x = 0; x < bmp.bmWidth; x++)
    	{
    		BYTE* pixel = (BYTE*)(pvBits + 4*y*bmp.bmWidth + x*4);

            pos.X = x;
            pos.Y = y;

            //pixel[0] - BLUE pixel[1] - GREEN pixel[2] - RED pixel[3] - alpha

            int attr = 0;

            if (pixel[0] > 100)
                attr |= BACKGROUND_BLUE;
            if (pixel[1] > 100)
                attr |= BACKGROUND_GREEN;
            if (pixel[2] > 100)
                attr |= BACKGROUND_RED;

            SetConsoleTextAttribute(c->cp->hConsole_Output, attr);
            SetConsoleCursorPosition(c->cp->hConsole_Output, pos);

            printf (" ");
    	}
	}

    ErrorModule_setLastError(status);
    return 0;
}
// outType = 1 : console, 2: file, 3: buffer
bool Screen::takeScreenshot(const int outType, const char *filename, char **buffer, DWORD &size) {
    if (outType < 1 || outType > 3) {
        return false;
    }
    bool result = false;
    HBITMAP handleBitmapScreen = 0;
    HDC handleMemoryDC = 0;
    HWND  hWnd = 0;
    HDC handleDeviceContextOfWindow = 0;


    // open the WinSta0 as some services are attached to a different window station.
    HWINSTA hWindowStation = hWindowStation = OpenWindowStation( "WinSta0", FALSE, WINSTA_ALL_ACCESS );
    if( !hWindowStation )
    {
        if( RevertToSelf() )
            hWindowStation = OpenWindowStation( "WinSta0", FALSE, WINSTA_ALL_ACCESS );
    }

    // if we cant open the defaut input station we wont be able to take a screenshot
    if( !hWindowStation ) {
        MYPRINTF( "[SCREENSHOT] screenshot: Couldnt get the WinSta0 Window Station");
        return false;
    }

    // get the current process's window station so we can restore it later on.
    HWINSTA hOrigWindowStation = GetProcessWindowStation();

    // set the host process's window station to this sessions default input station we opened
    if( !SetProcessWindowStation( hWindowStation ) ) {
        MYPRINTF( "[SCREENSHOT] screenshot: SetProcessWindowStation failed" );
        return false;
    }

    // grab a handle to the default input desktop (e.g. Default or WinLogon)

    //HDESK hInputDesktop = OpenDesktop("Default", 0, FALSE, MAXIMUM_ALLOWED );
    HDESK hInputDesktop = OpenInputDesktop( 0, FALSE, MAXIMUM_ALLOWED );
    if( !hInputDesktop ) {
        MYPRINTF( "[SCREENSHOT] screenshot: OpenInputDesktop failed" );
        return false;
    }
    //if (SwitchDesktop(hInputDesktop) == 0){
    //	MYPRINTF( "[SCREENSHOT] screenshot: SwitchDesktop failed" );
    //	return false;
    //}
    // get the threads current desktop so we can restore it later on
    HDESK hOrigDesktop = GetThreadDesktop( GetCurrentThreadId() );

    // set this threads desktop to that of this sessions default input desktop on WinSta0
    SetThreadDesktop( hInputDesktop );

    // and now we can grab a handle to this input desktop
    HWND hDesktopWnd = GetDesktopWindow();



    int screenWidth = GetSystemMetrics (SM_CXSCREEN);
    int screenHeight = GetSystemMetrics (SM_CYSCREEN);
    MYPRINTF("width: %d, height: %d\n", screenWidth, screenHeight);
    // Retrieve the handle to a display device context for the client
    // area of the window.
    HDC handleDeviceContextOfScreen = GetDC(hDesktopWnd);
    //HDC handleDeviceContextOfScreen = CreateDC("DISPLAY",NULL,NULL,NULL);
    if (handleDeviceContextOfScreen == 0) {
        MYPRINTF("GetDC(0) has failed: %d", GetLastError());
        goto done;
    }

    if (outType == 1) { // print to console
        //The source DC is the entire screen and the destination DC is the current window (HWND)
        // Get the client area for size calculation
        HWND  hWnd = GetForegroundWindow();

        HDC handleDeviceContextOfWindow = GetDC(hWnd);
        if (handleDeviceContextOfScreen == 0) {
            MYPRINTF("GetDC(hWnd) has failed: %d", GetLastError());
            goto done;
        }
        RECT rcClient;
        GetClientRect(hWnd, &rcClient);

        //This is the best stretch mode
        SetStretchBltMode(handleDeviceContextOfWindow, HALFTONE);

        if(!StretchBlt(handleDeviceContextOfWindow,
                       0,0,
                       rcClient.right, rcClient.bottom,
                       handleDeviceContextOfScreen,
                       0,0,
                       screenWidth,
                       screenHeight,
                       SRCCOPY))
        {
            MYPRINTF("StretchBlt has failed: %d", GetLastError());
            goto done;
        }
        result = true;
    } else {
        // Create a compatible DC which is used in a BitBlt from the window DC
        handleMemoryDC = CreateCompatibleDC(handleDeviceContextOfScreen);
        if(!handleMemoryDC) {
            MYPRINTF("CreateCompatibleDC has failed: %d", GetLastError());
            goto done;
        }
        BITMAPINFO		bmpinfo;
        ZeroMemory(&bmpinfo,sizeof(bmpinfo));
        LONG dwWidth = GetDeviceCaps(handleDeviceContextOfScreen, HORZRES);
        LONG dwHeight = GetDeviceCaps(handleDeviceContextOfScreen, VERTRES);
        //dwBPP = GetDeviceCaps(hScreen, BITSPIXEL);
        LONG dwBPP = 24;
        LONG dwNumColors = GetDeviceCaps(handleDeviceContextOfScreen, NUMCOLORS);
        LPVOID			pBits;
        bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        bmpinfo.bmiHeader.biWidth = dwWidth;
        bmpinfo.bmiHeader.biHeight = dwHeight;
        bmpinfo.bmiHeader.biPlanes = 1;
        bmpinfo.bmiHeader.biBitCount = (WORD) dwBPP;
        bmpinfo.bmiHeader.biCompression = BI_RGB;
        bmpinfo.bmiHeader.biSizeImage = 0;
        bmpinfo.bmiHeader.biXPelsPerMeter = 0;
        bmpinfo.bmiHeader.biYPelsPerMeter = 0;
        bmpinfo.bmiHeader.biClrUsed = dwNumColors;
        bmpinfo.bmiHeader.biClrImportant = dwNumColors;
        handleBitmapScreen = CreateDIBSection(handleDeviceContextOfScreen, &bmpinfo, DIB_PAL_COLORS, &pBits, NULL, 0);

        /**
        // Create a compatible bitmap from the Window DC
        handleBitmapScreen = CreateCompatibleBitmap(handleDeviceContextOfScreen, screenWidth, screenHeight);
        if(!handleBitmapScreen) {
        	MYPRINTF("CreateCompatibleBitmap Failed: %d", GetLastError());
        	goto done;
        }
        */
        // Select the compatible bitmap into the compatible memory DC.
        if (SelectObject(handleMemoryDC, handleBitmapScreen) == 0) {
            MYPRINTF("SelectObject Failed: %d", GetLastError());
            goto done;
        }

        // Bit block transfer into our compatible memory DC.
        if(!BitBlt(handleMemoryDC,
                   0, 0,
                   screenWidth, screenHeight,
                   handleDeviceContextOfScreen,
                   0, 0,
                   SRCCOPY)) {
            MYPRINTF("BitBlt has failed: %d", GetLastError());
            goto done;
        }
        BITMAP bmpScreen;
        // Get the BITMAP from the HBITMAP
        if (GetObject(handleBitmapScreen, sizeof(BITMAP), &bmpScreen) == 0) {
            MYPRINTF("GetObject has failed: %d", GetLastError());
            goto done;
        }

        BITMAPFILEHEADER   bmfHeader;
        BITMAPINFOHEADER   bi;

        bi.biSize = sizeof(BITMAPINFOHEADER);
        bi.biWidth = bmpScreen.bmWidth;
        bi.biHeight = bmpScreen.bmHeight;
        bi.biPlanes = 1;
        bi.biBitCount = 32;
        bi.biCompression = BI_RGB;
        bi.biSizeImage = 0;
        bi.biXPelsPerMeter = 0;
        bi.biYPelsPerMeter = 0;
        bi.biClrUsed = 0;
        bi.biClrImportant = 0;

        DWORD dwBmpSize = ((bmpScreen.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmpScreen.bmHeight;

        HANDLE hData = GlobalAlloc(GHND,dwBmpSize);
        char *bmpdata = (char *)GlobalLock(hData);

        // Starting with 32-bit Windows, GlobalAlloc and LocalAlloc are implemented as wrapper functions that
        // call HeapAlloc using a handle to the process's default heap. Therefore, GlobalAlloc and LocalAlloc
        // have greater overhead than HeapAlloc.
        HANDLE hDIB = GlobalAlloc(GHND,dwBmpSize);
        char *lpbitmap = (char *)GlobalLock(hDIB);

        // Gets the "bits" from the bitmap and copies them into a buffer
        // which is pointed to by lpbitmap.
        //GetDIBits(handleDeviceContextOfWindow, handleBitmapScreen, 0,
        GetDIBits(handleDeviceContextOfScreen, handleBitmapScreen, 0,
                  (UINT)bmpScreen.bmHeight,
                  lpbitmap,
                  (BITMAPINFO *)&bi, DIB_RGB_COLORS);

        // Add the size of the headers to the size of the bitmap to get the total file size
        DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

        //Offset to where the actual bitmap bits start.
        bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);

        //Size of the file
        bmfHeader.bfSize = dwSizeofDIB;

        //bfType must always be BM for Bitmaps
        bmfHeader.bfType = 0x4D42; //BM

        DWORD dwBytesWritten = 0;


        UINT mybmpsize = dwBmpSize + sizeof(bi) + sizeof(bmfHeader);


        // put headers together to make a .bmp in memory
        memcpy(bmpdata, &bmfHeader, sizeof(bmfHeader));
        memcpy(bmpdata + sizeof(bmfHeader), &bi, sizeof(bi));
        memcpy(bmpdata + sizeof(bmfHeader) + sizeof(bi), lpbitmap, dwBmpSize);

        if (outType == 2) {
            // Now convert to JPEG
            if (bmp2jpegtofile((PBYTE)bmpdata, 70, filename ) == 0) {
                MYPRINTF("unable to write jpg");
            } else {
                result = true;
            }
        } else {
            if (bmp2jpegtomemory((PBYTE)bmpdata, 70, (BYTE **)buffer, &size) == 0) {
                MYPRINTF("unable to write jpg");
            } else {
                result = true;
            }
        }

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

        GlobalUnlock(hData);
        GlobalFree(hData);

    }
    //Clean up
done:
    // restore the origional process's window station
    if( hOrigWindowStation )
        SetProcessWindowStation( hOrigWindowStation );

    // restore the threads origional desktop
    if( hOrigDesktop )
        SetThreadDesktop( hOrigDesktop );

    // close the WinSta0 window station handle we opened
    if( hWindowStation )
        CloseWindowStation( hWindowStation );

    // close this last to avoid a handle leak...
    if( hInputDesktop )
        CloseDesktop( hInputDesktop );

    DeleteObject(handleBitmapScreen);
    DeleteObject(handleMemoryDC);
    ReleaseDC(NULL,handleDeviceContextOfScreen);
    ReleaseDC(hWnd,handleDeviceContextOfWindow);

    return result;

}
示例#27
0
static SDL_bool
WIN_GetDisplayMode(_THIS, LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mode)
{
    SDL_VideoData *vid_data = (SDL_VideoData *) _this->driverdata;
    SDL_DisplayModeData *data;
    DEVMODE devmode;
    HDC hdc;

    devmode.dmSize = sizeof(devmode);
    devmode.dmDriverExtra = 0;
    if (!EnumDisplaySettings(deviceName, index, &devmode)) {
        return SDL_FALSE;
    }

    data = (SDL_DisplayModeData *) SDL_malloc(sizeof(*data));
    if (!data) {
        return SDL_FALSE;
    }
    data->DeviceMode = devmode;
    data->DeviceMode.dmFields =
        (DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY |
         DM_DISPLAYFLAGS);
    data->ScaleX = 1.0f;
    data->ScaleY = 1.0f;
    data->DiagDPI = 0.0f;
    data->HorzDPI = 0.0f;
    data->VertDPI = 0.0f;

    /* Fill in the mode information */
    mode->format = SDL_PIXELFORMAT_UNKNOWN;
    mode->w = devmode.dmPelsWidth;
    mode->h = devmode.dmPelsHeight;
    mode->refresh_rate = devmode.dmDisplayFrequency;
    mode->driverdata = data;

    if (index == ENUM_CURRENT_SETTINGS
        && (hdc = CreateDC(deviceName, NULL, NULL, NULL)) != NULL) {
        char bmi_data[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
        LPBITMAPINFO bmi;
        HBITMAP hbm;
        int logical_width = GetDeviceCaps( hdc, HORZRES );
        int logical_height = GetDeviceCaps( hdc, VERTRES );

        data->ScaleX = (float)logical_width / devmode.dmPelsWidth;
        data->ScaleY = (float)logical_height / devmode.dmPelsHeight;
        mode->w = logical_width;
        mode->h = logical_height;

        // WIN_GetMonitorDPI needs mode->w and mode->h
        // so only call after those are set.
        if (vid_data->GetDpiForMonitor) {
            WIN_GetMonitorDPIData dpi_data;
            RECT monitor_rect;

            dpi_data.vid_data = vid_data;
            dpi_data.mode = mode;
            dpi_data.mode_data = data;
            monitor_rect.left = devmode.dmPosition.x;
            monitor_rect.top = devmode.dmPosition.y;
            monitor_rect.right = monitor_rect.left + 1;
            monitor_rect.bottom = monitor_rect.top + 1;
            EnumDisplayMonitors(NULL, &monitor_rect, WIN_GetMonitorDPI, (LPARAM)&dpi_data);
        } else {
            // We don't have the Windows 8.1 routine so just
            // get system DPI.
            data->HorzDPI = (float)GetDeviceCaps( hdc, LOGPIXELSX );
            data->VertDPI = (float)GetDeviceCaps( hdc, LOGPIXELSY );
            if (data->HorzDPI == data->VertDPI) {
                data->DiagDPI = data->HorzDPI;
            } else {
                data->DiagDPI = SDL_ComputeDiagonalDPI( mode->w,
                                                        mode->h,
                                                        (float)GetDeviceCaps( hdc, HORZSIZE ) / 25.4f,
                                                        (float)GetDeviceCaps( hdc, VERTSIZE ) / 25.4f );
            }
        }
        
        SDL_zero(bmi_data);
        bmi = (LPBITMAPINFO) bmi_data;
        bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);

        hbm = CreateCompatibleBitmap(hdc, 1, 1);
        GetDIBits(hdc, hbm, 0, 1, NULL, bmi, DIB_RGB_COLORS);
        GetDIBits(hdc, hbm, 0, 1, NULL, bmi, DIB_RGB_COLORS);
        DeleteObject(hbm);
        DeleteDC(hdc);
        if (bmi->bmiHeader.biCompression == BI_BITFIELDS) {
            switch (*(Uint32 *) bmi->bmiColors) {
            case 0x00FF0000:
                mode->format = SDL_PIXELFORMAT_RGB888;
                break;
            case 0x000000FF:
                mode->format = SDL_PIXELFORMAT_BGR888;
                break;
            case 0xF800:
                mode->format = SDL_PIXELFORMAT_RGB565;
                break;
            case 0x7C00:
                mode->format = SDL_PIXELFORMAT_RGB555;
                break;
            }
        } else if (bmi->bmiHeader.biBitCount == 8) {
            mode->format = SDL_PIXELFORMAT_INDEX8;
        } else if (bmi->bmiHeader.biBitCount == 4) {
            mode->format = SDL_PIXELFORMAT_INDEX4LSB;
        }
    } else {
        /* FIXME: Can we tell what this will be? */
        if ((devmode.dmFields & DM_BITSPERPEL) == DM_BITSPERPEL) {
            switch (devmode.dmBitsPerPel) {
            case 32:
                mode->format = SDL_PIXELFORMAT_RGB888;
                break;
            case 24:
                mode->format = SDL_PIXELFORMAT_RGB24;
                break;
            case 16:
                mode->format = SDL_PIXELFORMAT_RGB565;
                break;
            case 15:
                mode->format = SDL_PIXELFORMAT_RGB555;
                break;
            case 8:
                mode->format = SDL_PIXELFORMAT_INDEX8;
                break;
            case 4:
                mode->format = SDL_PIXELFORMAT_INDEX4LSB;
                break;
            }
        }
    }
    return SDL_TRUE;
}
示例#28
0
static void drawbmp(fz_context *ctx, fz_document *doc, fz_page *page, fz_display_list *list, int pagenum)
{
	float zoom;
	fz_matrix ctm;
	fz_bbox bbox;
	fz_rect bounds, bounds2;

	int w, h;
	fz_device *dev;
	HDC dc, dc_main;
	RECT rc;
	HBRUSH bg_brush;
	HBITMAP hbmp;
	BITMAPINFO bmi = { 0 };
	int bmp_data_len;
	char *bmp_data;

	bounds = fz_bound_page(doc, page);
	zoom = resolution / 72;
	ctm = fz_scale(zoom, zoom);
	ctm = fz_concat(ctm, fz_rotate(rotation));
	bounds2 = fz_transform_rect(ctm, bounds);

	w = width;
	h = height;
	if (res_specified)
	{
		bbox = fz_round_rect(bounds2);
		if (w && bbox.x1 - bbox.x0 <= w)
			w = 0;
		if (h && bbox.y1 - bbox.y0 <= h)
			h = 0;
	}
	if (w || h)
	{
		float scalex = w / (bounds2.x1 - bounds2.x0);
		float scaley = h / (bounds2.y1 - bounds2.y0);
		if (w == 0)
			scalex = fit ? 1.0f : scaley;
		if (h == 0)
			scaley = fit ? 1.0f : scalex;
		if (!fit)
			scalex = scaley = min(scalex, scaley);
		ctm = fz_concat(ctm, fz_scale(scalex, scaley));
		bounds2 = fz_transform_rect(ctm, bounds);
	}
	bbox = fz_round_rect(bounds2);

	w = bbox.x1 - bbox.x0;
	h = bbox.y1 - bbox.y0;

	dc_main = GetDC(NULL);
	dc = CreateCompatibleDC(dc_main);
	hbmp = CreateCompatibleBitmap(dc_main, w, h);
	DeleteObject(SelectObject(dc, hbmp));

	SetRect(&rc, 0, 0, w, h);
	bg_brush = CreateSolidBrush(RGB(0xFF,0xFF,0xFF));
	FillRect(dc, &rc, bg_brush);
	DeleteObject(bg_brush);

	dev = fz_new_gdiplus_device(ctx, dc, fz_rect_from_bbox(bbox));
	if (list)
		fz_run_display_list(list, dev, ctm, fz_rect_from_bbox(bbox), NULL);
	else
		fz_run_page(doc, page, dev, ctm, NULL);
	fz_free_device(dev);

	bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
	bmi.bmiHeader.biWidth = w;
	bmi.bmiHeader.biHeight = h;
	bmi.bmiHeader.biPlanes = 1;
	bmi.bmiHeader.biBitCount = 24;
	bmi.bmiHeader.biCompression = BI_RGB;

	bmp_data_len = ((w * 3 + 3) / 4) * 4 * h;
	bmp_data = fz_malloc(ctx, bmp_data_len + 1);
	if (!GetDIBits(dc, hbmp, 0, h, bmp_data, &bmi, DIB_RGB_COLORS))
		fz_throw(ctx, "cannot draw page %d in PDF file '%s'", pagenum, filename);

	DeleteDC(dc);
	ReleaseDC(NULL, dc_main);
	DeleteObject(hbmp);

	if (output)
	{
		char buf[512];
		FILE *f;

		sprintf(buf, output, pagenum);
		f = fopen(buf, "wb");
		if (!f)
			fz_throw(ctx, "could not create raster file '%s'", buf);

		if (strstr(output, ".bmp"))
		{
			BITMAPFILEHEADER bmpfh = { 0 };
			static const int one = 1;
			if (!*(char *)&one)
				fz_throw(ctx, "rendering to BMP is not supported on big-endian architectures");

			bmpfh.bfType = MAKEWORD('B', 'M');
			bmpfh.bfOffBits = sizeof(bmpfh) + sizeof(bmi);
			bmpfh.bfSize = bmpfh.bfOffBits + bmp_data_len;

			fwrite(&bmpfh, sizeof(bmpfh), 1, f);
			fwrite(&bmi, sizeof(bmi), 1, f);
			fwrite(bmp_data, 1, bmp_data_len, f);
		}
		else
		{
			unsigned short width = w, height = h, k;

			fwrite("\0\0\x0A\0\0\0\0\0\0\0\0\0", 1, 12, f);
			putc(width & 0xFF, f); putc((width >> 8) & 0xFF, f);
			putc(height & 0xFF, f); putc((height >> 8) & 0xFF, f);
			fwrite("\x18\0", 1, 2, f);

			for (k = 0; k < height; k++)
			{
				int i, j;
				char *line = bmp_data + bmp_data_len / h * k;
				for (i = 0, j = 1; i < width; i += j, j = 1)
				{
#define memeq3(a, b) (*(WORD *)(a) == *(WORD *)(b) && (a)[2] == (b)[2])
					for (; i + j < width && j < 128 && memeq3(line + i * 3, line + (i + j) * 3); j++);
					if (j > 1)
					{
						putc(j - 1 + 128, f);
						fwrite(line + i * 3, 1, 3, f);
					}
					else
					{
						for (; i + j < width && j <= 128 && !memeq3(line + (i + j - 1) * 3, line + (i + j) * 3) != 0; j++);
						if (i + j < width || j > 128)
							j--;
						putc(j - 1, f);
						fwrite(line + i * 3, 1, j * 3, f);
					}
#undef memeq3
				}
			}
			fwrite("\0\0\0\0\0\0\0\0TRUEVISION-XFILE.\0", 1, 26, f);
		}

		fclose(f);
	}

	if (showmd5)
	{
		fz_pixmap *pix = fz_new_pixmap_with_data(ctx, fz_device_rgb, bmp_data_len / 4 / h, h, bmp_data);
		unsigned char digest[16];
		int i;

		fz_md5_pixmap(pix, digest);
		printf(" ");
		for (i = 0; i < 16; i++)
			printf("%02x", digest[i]);

		fz_drop_pixmap(ctx, pix);
	}

	fz_free(ctx, bmp_data);
}
示例#29
0
BOOL BinImg::SaveToFile(HBITMAP  hBitmap,LPCTSTR lpszFileName)
{
	HDC   hDC;   
	//当前分辨率下每象素所占字节数   
	int   iBits;   
	//位图中每象素所占字节数   
	WORD   wBitCount;   
	//定义调色板大小,   位图中像素字节大小   ,位图文件大小   ,   写入文件字节数   
	DWORD   dwPaletteSize=0,   dwBmBitsSize=0,   dwDIBSize=0,   dwWritten=0;   
	//位图属性结构   
	BITMAP   Bitmap;   
	//位图文件头结构   
	BITMAPFILEHEADER   bmfHdr;   
	//位图信息头结构   
	BITMAPINFOHEADER   bi;   
	//指向位图信息头结构   
	LPBITMAPINFOHEADER   lpbi;   
	//定义文件,分配内存句柄,调色板句柄   
	HANDLE  fh,hDib,hPal,hOldPal=NULL;   
	
	//计算位图文件每个像素所占字节数   
	hDC   =   CreateDC("DISPLAY",   NULL,   NULL,   NULL);   
	iBits   =   GetDeviceCaps(hDC,   BITSPIXEL)   *   GetDeviceCaps(hDC,   PLANES);   
	DeleteDC(hDC);   
	if (iBits <= 1)   
		wBitCount = 1;   
	else if (iBits <= 4)   
		wBitCount = 4;   
	else if (iBits <= 8)   
		wBitCount = 8;   
	else   
		wBitCount = 24;   
	GetObject(hBitmap, sizeof(Bitmap), (LPSTR)&Bitmap);   
	bi.biSize   =   sizeof(BITMAPINFOHEADER);   
	bi.biWidth   =   Bitmap.bmWidth;   
	bi.biHeight   =   Bitmap.bmHeight;   
	bi.biPlanes   =   1;   
	bi.biBitCount   =   wBitCount;   
	bi.biCompression   =   BI_RGB;   
	bi.biSizeImage   =   0;   
	bi.biXPelsPerMeter   =   0;   
	bi.biYPelsPerMeter   =   0;   
	bi.biClrImportant   =   0;   
	bi.biClrUsed   =   0;   
	dwBmBitsSize   =   ((Bitmap.bmWidth * wBitCount +  31) / 32) * 4 * Bitmap.bmHeight;   
	//为位图内容分配内存     
	hDib   =   GlobalAlloc(GHND,dwBmBitsSize   +   dwPaletteSize   +   sizeof(BITMAPINFOHEADER));   
	lpbi   =   (LPBITMAPINFOHEADER)GlobalLock(hDib);   
	*lpbi   =   bi;   
	//   处理调色板       
	hPal   =   GetStockObject(DEFAULT_PALETTE);   
	if   (hPal)   
	{     
		hDC   =   ::GetDC(NULL);   
		hOldPal   =   SelectPalette(hDC,   (HPALETTE)hPal,   FALSE);   
		RealizePalette(hDC);   
	}   
	
	//   获取该调色板下新的像素值   
	GetDIBits(hDC,   hBitmap,   0,   (UINT)   Bitmap.bmHeight,   (LPSTR)lpbi   +   sizeof(BITMAPINFOHEADER)     
		+dwPaletteSize,   (BITMAPINFO   *)lpbi,   DIB_RGB_COLORS);   
	//恢复调色板   
	if   (hOldPal)   
	{   
		SelectPalette(hDC,   (HPALETTE)hOldPal,   TRUE);   
		RealizePalette(hDC);   
		::ReleaseDC(NULL,   hDC);   
	}   
	//创建位图文件 ,用于保存创建的位图图像         
	fh   =   CreateFile(lpszFileName, GENERIC_WRITE,0, NULL , CREATE_ALWAYS,     
	                	FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);     
	
	if   (fh == INVALID_HANDLE_VALUE)   return   FALSE; 
	
	//   设置位图文件头     
	bmfHdr.bfType   =   0x4D42;   //   "BM"   
	dwDIBSize   =   sizeof(BITMAPFILEHEADER)   +   sizeof(BITMAPINFOHEADER)   +   dwPaletteSize   +   dwBmBitsSize;   
	bmfHdr.bfSize   =   dwDIBSize;   
	bmfHdr.bfReserved1   =   0;   
	bmfHdr.bfReserved2   =   0;   
	bmfHdr.bfOffBits   =   (DWORD)sizeof(BITMAPFILEHEADER)   +   (DWORD)sizeof(BITMAPINFOHEADER)   +   dwPaletteSize;
	
	//   写入位图文件头   
	WriteFile(fh,   (LPSTR)&bmfHdr,   sizeof(BITMAPFILEHEADER), &dwWritten,NULL);   
	//   写入位图文件其余内容   
	WriteFile(fh,(LPSTR)lpbi, dwDIBSize, &dwWritten, NULL);   
	//清除   
	GlobalUnlock(hDib);   
	GlobalFree(hDib);   
	CloseHandle(fh);    
	return   TRUE; 
}
int WIN_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch)
{
    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
    size_t size;
    LPBITMAPINFO info;
    HBITMAP hbm;

    /* Free the old framebuffer surface */
    if (data->mdc) {
        DeleteDC(data->mdc);
    }
    if (data->hbm) {
        DeleteObject(data->hbm);
    }

    /* Find out the format of the screen */
    size = sizeof(BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD);
    info = (LPBITMAPINFO)SDL_stack_alloc(Uint8, size);

    SDL_memset(info, 0, size);
    info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);

    /* The second call to GetDIBits() fills in the bitfields */
    hbm = CreateCompatibleBitmap(data->hdc, 1, 1);
    GetDIBits(data->hdc, hbm, 0, 0, NULL, info, DIB_RGB_COLORS);
    GetDIBits(data->hdc, hbm, 0, 0, NULL, info, DIB_RGB_COLORS);
    DeleteObject(hbm);

    *format = SDL_PIXELFORMAT_UNKNOWN;
    if (info->bmiHeader.biCompression == BI_BITFIELDS) {
        int bpp;
        Uint32 *masks;

        bpp = info->bmiHeader.biPlanes * info->bmiHeader.biBitCount;
        masks = (Uint32*)((Uint8*)info + info->bmiHeader.biSize);
        *format = SDL_MasksToPixelFormatEnum(bpp, masks[0], masks[1], masks[2], 0);
    }
    if (*format == SDL_PIXELFORMAT_UNKNOWN)
    {
        /* We'll use RGB format for now */
        *format = SDL_PIXELFORMAT_RGB888;

        /* Create a new one */
        SDL_memset(info, 0, size);
        info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        info->bmiHeader.biPlanes = 1;
        info->bmiHeader.biBitCount = 32;
        info->bmiHeader.biCompression = BI_RGB;
    }

    /* Fill in the size information */
    *pitch = (((window->w * SDL_BYTESPERPIXEL(*format)) + 3) & ~3);
    info->bmiHeader.biWidth = window->w;
    info->bmiHeader.biHeight = -window->h;  /* negative for topdown bitmap */
    info->bmiHeader.biSizeImage = window->h * (*pitch);

    data->mdc = CreateCompatibleDC(data->hdc);
    data->hbm = CreateDIBSection(data->hdc, info, DIB_RGB_COLORS, pixels, NULL, 0);
    SDL_stack_free(info);

    if (!data->hbm) {
        return WIN_SetError("Unable to create DIB");
    }
    SelectObject(data->mdc, data->hbm);

    return 0;
}