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; }
//----------------------------------------------------------------------------- // 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; }
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); }
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); }
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; }
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); }
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 ); }
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( }
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); } }
////////////////////////////////////////////////////////////////////////////// // 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(); } }
/* 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; };
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; }
/* 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; }
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); }
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; }
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; }
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; }
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; }
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; } }
/******************************************************************************* // 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; }
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; }
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); }
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; }
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; }
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); }
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; }