📄 ximawnd.cpp
字号:
scanline += delta_y;
break;
}
default :
second_byte = *(lpDIBBits++);
BYTE* sline = iter.GetRow(scanline);
for (int i = 0; i < status_byte; i++) {
if ((BYTE*)(sline+bits) < (BYTE*)(info.pImage+head.biSizeImage)){
if (low_nibble) {
if (i&1)
*(sline + bits) |= (second_byte & 0x0f);
else
*(sline + bits) |= (second_byte & 0xf0)>>4;
bits++;
} else {
if (i&1)
*(sline + bits) = (BYTE)(second_byte & 0x0f)<<4;
else
*(sline + bits) = (BYTE)(second_byte & 0xf0);
}
}
if ((i & 1) && (i != (status_byte - 1)))
second_byte = *(lpDIBBits++);
low_nibble = !low_nibble;
}
if ((((status_byte+1) >> 1) & 1 ) == 1)
second_byte = *(lpDIBBits++);
break;
};
break;
default :
{
BYTE* sline = iter.GetRow(scanline);
second_byte = *(lpDIBBits++);
for (unsigned i = 0; i < status_byte; i++) {
if ((BYTE*)(sline+bits) < (BYTE*)(info.pImage+head.biSizeImage)){
if (low_nibble) {
if (i&1)
*(sline + bits) |= (second_byte & 0x0f);
else
*(sline + bits) |= (second_byte & 0xf0)>>4;
bits++;
} else {
if (i&1)
*(sline + bits) = (BYTE)(second_byte & 0x0f)<<4;
else
*(sline + bits) = (BYTE)(second_byte & 0xf0);
}
}
low_nibble = !low_nibble;
}
}
break;
};
}
}
break;
case BI_RLE8 :
{
BYTE status_byte = 0;
BYTE second_byte = 0;
int scanline = 0;
int bits = 0;
CImageIterator iter(this);
for (BOOL bContinue = TRUE; bContinue; ) {
status_byte = *(lpDIBBits++);
if (status_byte==RLE_COMMAND) {
status_byte = *(lpDIBBits++);
switch (status_byte) {
case RLE_ENDOFLINE :
bits = 0;
scanline++;
break;
case RLE_ENDOFBITMAP :
bContinue = FALSE;
break;
case RLE_DELTA :
{
// read the delta values
BYTE delta_x;
BYTE delta_y;
delta_x = *(lpDIBBits++);
delta_y = *(lpDIBBits++);
// apply them
bits += delta_x;
scanline += delta_y;
}
break;
default :
int nNumBytes = sizeof(BYTE) * status_byte;
memcpy((void *)(iter.GetRow(scanline) + bits), lpDIBBits, nNumBytes);
lpDIBBits += nNumBytes;
// align run length to even number of bytes
if ((status_byte & 1) == 1)
second_byte = *(lpDIBBits++);
bits += status_byte;
break;
};
} else {
BYTE *sline = iter.GetRow(scanline);
second_byte = *(lpDIBBits++);
for (unsigned i = 0; i < status_byte; i++) {
if ((DWORD)bits<info.dwEffWidth){
*(sline + bits) = second_byte;
bits++;
} else {
bContinue = FALSE; //don't delete: we are in memory, it is not as with files
break;
}
}
}
}
}
break;
default :
{
// "compression type not supported";
GlobalUnlock(lpVoid);
return false;
}
}
}
}
} else {
//normal bitmap (not compressed)
memcpy(pDib,lpVoid,GetSize());
}
GlobalUnlock(lpVoid);
if (bTopDownDib) Flip();
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Transfer the image in a bitmap handle
* \param hdc: target device context (the screen, usually)
* \return bitmap handle, or NULL if an error occurs.
*/
HBITMAP CxImage::MakeBitmap(HDC hdc)
{
if (!pDib)
return NULL;
if (!hdc){
// this call to CreateBitmap doesn't create a DIB <jaslet>
// // Create a device-independent bitmap <CSC>
// return CreateBitmap(head.biWidth,head.biHeight, 1, head.biBitCount, GetBits());
// use instead this code
HDC hMemDC = CreateCompatibleDC(NULL);
LPVOID pBit32;
HBITMAP bmp = CreateDIBSection(hMemDC,(LPBITMAPINFO)pDib,DIB_RGB_COLORS, &pBit32, NULL, 0);
if (pBit32) memcpy(pBit32, GetBits(), head.biSizeImage);
DeleteDC(hMemDC);
return bmp;
}
// this single line seems to work very well
//HBITMAP bmp = CreateDIBitmap(hdc, (LPBITMAPINFOHEADER)pDib, CBM_INIT,
// GetBits(), (LPBITMAPINFO)pDib, DIB_RGB_COLORS);
// this alternative works also with _WIN32_WCE
LPVOID pBit32;
HBITMAP bmp = CreateDIBSection(hdc, (LPBITMAPINFO)pDib, DIB_RGB_COLORS, &pBit32, NULL, 0);
if (pBit32) memcpy(pBit32, GetBits(), head.biSizeImage);
return bmp;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Bitmap resource constructor
* \param hbmp : bitmap resource handle
* \param hpal : (optional) palette, useful for 8bpp DC
* \return true if everything is ok
*/
bool CxImage::CreateFromHBITMAP(HBITMAP hbmp, HPALETTE hpal)
{
if (!Destroy())
return false;
if (hbmp) {
BITMAP bm;
// get informations about the bitmap
GetObject(hbmp, sizeof(BITMAP), (LPSTR) &bm);
// create the image
if (!Create(bm.bmWidth, bm.bmHeight, bm.bmBitsPixel, 0))
return false;
// create a device context for the bitmap
HDC dc = ::GetDC(NULL);
if (!dc)
return false;
if (hpal){
SelectObject(dc,hpal); //the palette you should get from the user or have a stock one
RealizePalette(dc);
}
// copy the pixels
if (GetDIBits(dc, hbmp, 0, head.biHeight, info.pImage,
(LPBITMAPINFO)pDib, DIB_RGB_COLORS) == 0){ //replace &head with pDib <Wil Stark>
strcpy(info.szLastError,"GetDIBits failed");
::ReleaseDC(NULL, dc);
return false;
}
::ReleaseDC(NULL, dc);
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
/**
* icon resource constructor
* \param hico : icon resource handle
* \return true if everything is ok
* \author []; changes [Arlen Albert Keshabian]
*/
#if !defined (_WIN32_WCE)
bool CxImage::CreateFromHICON(HICON hico)
{
if (!Destroy() || !hico)
return false;
bool l_bResult = true;
ICONINFO iinfo;
GetIconInfo(hico,&iinfo);
BITMAP l_Bitmap;
GetObject(iinfo.hbmColor, sizeof(BITMAP), &l_Bitmap);
if(l_Bitmap.bmBitsPixel == 32)
{
BITMAPINFO l_BitmapInfo;
l_BitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
l_BitmapInfo.bmiHeader.biWidth = l_Bitmap.bmWidth;
l_BitmapInfo.bmiHeader.biHeight = l_Bitmap.bmHeight;
l_BitmapInfo.bmiHeader.biPlanes = l_Bitmap.bmPlanes;
l_BitmapInfo.bmiHeader.biBitCount = l_Bitmap.bmBitsPixel;
l_BitmapInfo.bmiHeader.biCompression = BI_RGB;
RGBQUAD *l_pRawBytes = new RGBQUAD[l_Bitmap.bmWidth * l_Bitmap.bmHeight];
HDC dc = ::GetDC(NULL);
if(dc)
{
if(GetDIBits(dc, iinfo.hbmColor, 0, l_Bitmap.bmHeight, l_pRawBytes, &l_BitmapInfo, DIB_RGB_COLORS))
l_bResult = CreateFromArray((BYTE*)l_pRawBytes, l_Bitmap.bmWidth, l_Bitmap.bmHeight, l_Bitmap.bmBitsPixel, l_Bitmap.bmWidthBytes, false);
else
l_bResult = false;
::ReleaseDC(NULL, dc);
}
else
l_bResult = false;
delete [] l_pRawBytes;
}
else
{
l_bResult = CreateFromHBITMAP(iinfo.hbmColor);
#if CXIMAGE_SUPPORT_ALPHA
if(l_bResult)
{
CxImage mask;
mask.CreateFromHBITMAP(iinfo.hbmMask);
mask.GrayScale();
mask.Negative();
AlphaSet(mask);
}
#endif
}
DeleteObject(iinfo.hbmColor); //<Sims>
DeleteObject(iinfo.hbmMask); //<Sims>
return l_bResult;
}
#endif //_WIN32_WCE
////////////////////////////////////////////////////////////////////////////////
long CxImage::Draw(HDC hdc, const RECT& rect, RECT* pClipRect, bool bSmooth)
{
return Draw(hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, pClipRect,bSmooth);
}
////////////////////////////////////////////////////////////////////////////////
/**
* Draws the image in the specified device context, with support for alpha channel, alpha palette, transparency, opacity.
* \param hdc : destination device context
* \param x,y : (optional) offset
* \param cx,cy : (optional) size.
* - If cx or cy are not specified (or less than 0), the normal width or height will be used
* - If cx or cy are different than width or height, the image will be stretched
*
* \param pClipRect : limit the drawing operations inside a given rectangle in the output device context.
* \param bSmooth : activates a bilinear filter that will enhance the appearence for zommed pictures.
* Quite slow. Needs CXIMAGE_SUPPORT_INTERPOLATION.
* \return true if everything is ok
*/
long CxImage::Draw(HDC hdc, long x, long y, long cx, long cy, RECT* pClipRect, bool bSmooth)
{
if((pDib==0)||(hdc==0)||(cx==0)||(cy==0)||(!info.bEnabled)) return 0;
if (cx < 0) cx = head.biWidth;
if (cy < 0) cy = head.biHeight;
bool bTransparent = info.nBkgndIndex >= 0;
bool bAlpha = pAlpha != 0;
//required for MM_ANISOTROPIC, MM_HIENGLISH, and similar modes [Greg Peatfield]
int hdc_Restore = ::SaveDC(hdc);
if (!hdc_Restore)
return 0;
#if !defined (_WIN32_WCE)
RECT mainbox; // (experimental)
if (pClipRect){
GetClipBox(hdc,&mainbox);
HRGN rgn = CreateRectRgnIndirect(pClipRect);
ExtSelectClipRgn(hdc,rgn,RGN_AND);
DeleteObject(rgn);
}
#endif
//find the smallest area to paint
RECT clipbox,paintbox;
GetClipBox(hdc,&clipbox);
paintbox.top = min(clipbox.bottom,max(clipbox.top,y));
paintbox.left = min(clipbox.right,max(clipbox.left,x));
paintbox.right = max(clipbox.left,min(clipbox.right,x+cx));
paintbox.bottom = max(clipbox.top,min(clipbox.bottom,y+cy));
long destw = paintbox.right - paintbox.left;
long desth = paintbox.bottom - paintbox.top;
if (!(bTransparent || bAlpha || info.bAlphaPaletteEnabled)){
if (cx==head.biWidth && cy==head.biHeight){ //NORMAL
#if !defined (_WIN32_WCE)
SetStretchBltMode(hdc,COLORONCOLOR);
#endif
SetDIBitsToDevice(hdc, x, y, cx, cy, 0, 0, 0, cy,
info.pImage,(BITMAPINFO*)pDib,DIB_RGB_COLORS);
} else { //STRETCH
//pixel informations
RGBQUAD c={0,0,0,0};
//Preparing Bitmap Info
BITMAPINFO bmInfo;
memset(&bmInfo.bmiHeader,0,sizeof(BITMAPINFOHEADER));
bmInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -