📄 ximapal.cpp
字号:
// xImaPal.cpp : Palette and Pixel functions
/* 07/08/2001 v1.00 - Davide Pizzolato - www.xdp.it
* CxImage version 5.99a 08/Feb/2004
*/
#include "ximage.h"
////////////////////////////////////////////////////////////////////////////////
// returns the palette dimension in byte
DWORD CxImage::GetPaletteSize()
{
return (head.biClrUsed * sizeof(RGBQUAD));
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::SetPaletteColor(BYTE idx, BYTE r, BYTE g, BYTE b, BYTE alpha)
{
if ((pDib)&&(head.biClrUsed)){
BYTE* iDst = (BYTE*)(pDib) + sizeof(BITMAPINFOHEADER);
if (idx<head.biClrUsed){
long ldx=idx*sizeof(RGBQUAD);
iDst[ldx++] = (BYTE) b;
iDst[ldx++] = (BYTE) g;
iDst[ldx++] = (BYTE) r;
iDst[ldx] = (BYTE) alpha;
info.last_c_isvalid = false;
}
}
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::SetPaletteColor(BYTE idx, RGBQUAD c)
{
if ((pDib)&&(head.biClrUsed)){
BYTE* iDst = (BYTE*)(pDib) + sizeof(BITMAPINFOHEADER);
if (idx<head.biClrUsed){
long ldx=idx*sizeof(RGBQUAD);
iDst[ldx++] = (BYTE) c.rgbBlue;
iDst[ldx++] = (BYTE) c.rgbGreen;
iDst[ldx++] = (BYTE) c.rgbRed;
iDst[ldx] = (BYTE) c.rgbReserved;
info.last_c_isvalid = false;
}
}
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::SetPaletteColor(BYTE idx, COLORREF cr)
{
if ((pDib)&&(head.biClrUsed)){
BYTE* iDst = (BYTE*)(pDib) + sizeof(BITMAPINFOHEADER);
if (idx<head.biClrUsed){
long ldx=idx*sizeof(RGBQUAD);
iDst[ldx++] = (BYTE) GetBValue(cr);
iDst[ldx++] = (BYTE) GetGValue(cr);
iDst[ldx++] = (BYTE) GetRValue(cr);
iDst[ldx] = (BYTE) 0;
info.last_c_isvalid = false;
}
}
}
////////////////////////////////////////////////////////////////////////////////
// returns the pointer to the first palette index
RGBQUAD* CxImage::GetPalette() const
{
if ((pDib)&&(head.biClrUsed))
return (RGBQUAD*)((BYTE*)pDib + sizeof(BITMAPINFOHEADER));
return NULL;
}
////////////////////////////////////////////////////////////////////////////////
RGBQUAD CxImage::GetPaletteColor(BYTE idx)
{
RGBQUAD rgb = {0,0,0,0};
if ((pDib)&&(head.biClrUsed)){
BYTE* iDst = (BYTE*)(pDib) + sizeof(BITMAPINFOHEADER);
if (idx<head.biClrUsed){
long ldx=idx*sizeof(RGBQUAD);
rgb.rgbBlue = iDst[ldx++];
rgb.rgbGreen=iDst[ldx++];
rgb.rgbRed =iDst[ldx++];
rgb.rgbReserved = iDst[ldx];
}
}
return rgb;
}
////////////////////////////////////////////////////////////////////////////////
BYTE CxImage::GetPixelIndex(long x,long y)
{
if ((pDib==NULL)||(head.biClrUsed==0)) return 0;
if ((x<0)||(y<0)||(x>=head.biWidth)||(y>=head.biHeight)) {
if (info.nBkgndIndex != -1) return (BYTE)info.nBkgndIndex;
else return *info.pImage;
}
if (head.biBitCount==8){
return info.pImage[y*info.dwEffWidth + x];
} else {
BYTE pos;
BYTE iDst= info.pImage[y*info.dwEffWidth + (x*head.biBitCount >> 3)];
if (head.biBitCount==4){
pos = (BYTE)(4*(1-x%2));
iDst &= (0x0F<<pos);
return (BYTE)(iDst >> pos);
} else if (head.biBitCount==1){
pos = (BYTE)(7-x%8);
iDst &= (0x01<<pos);
return (BYTE)(iDst >> pos);
}
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////
RGBQUAD CxImage::GetPixelColor(long x,long y, bool bGetAlpha)
{
// RGBQUAD rgb={0,0,0,0};
RGBQUAD rgb=info.nBkgndColor; //<mpwolski>
if ((pDib==NULL)||(x<0)||(y<0)||
(x>=head.biWidth)||(y>=head.biHeight)){
if (info.nBkgndIndex != -1){
if (head.biBitCount<24) rgb = GetPaletteColor((BYTE)info.nBkgndIndex);
else rgb = info.nBkgndColor;
} else if (pDib) rgb = GetPixelColor(0,0);
return rgb;
}
if (head.biClrUsed){
rgb = GetPaletteColor(GetPixelIndex(x,y));
} else {
BYTE* iDst = info.pImage + y*info.dwEffWidth + x*3;
rgb.rgbBlue = *iDst++;
rgb.rgbGreen= *iDst++;
rgb.rgbRed = *iDst;
}
#if CXIMAGE_SUPPORT_ALPHA
if (pAlpha && bGetAlpha) rgb.rgbReserved = AlphaGet(x,y);
#else
rgb.rgbReserved = 0;
#endif //CXIMAGE_SUPPORT_ALPHA
return rgb;
}
////////////////////////////////////////////////////////////////////////////////
BYTE CxImage::GetPixelGray(long x, long y)
{
RGBQUAD color = GetPixelColor(x,y);
return (BYTE)RGB2GRAY(color.rgbRed,color.rgbGreen,color.rgbBlue);
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::SetPixelIndex(long x,long y,BYTE i)
{
if ((pDib==NULL)||(head.biClrUsed==0)||
(x<0)||(y<0)||(x>=head.biWidth)||(y>=head.biHeight)) return ;
if (head.biBitCount==8){
info.pImage[y*info.dwEffWidth + x]=i;
return;
} else {
BYTE pos;
BYTE* iDst= info.pImage + y*info.dwEffWidth + (x*head.biBitCount >> 3);
if (head.biBitCount==4){
pos = (BYTE)(4*(1-x%2));
*iDst &= ~(0x0F<<pos);
*iDst |= ((i & 0x0F)<<pos);
return;
} else if (head.biBitCount==1){
pos = (BYTE)(7-x%8);
*iDst &= ~(0x01<<pos);
*iDst |= ((i & 0x01)<<pos);
return;
}
}
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::SetPixelColor(long x,long y,COLORREF cr)
{
SetPixelColor(x,y,RGBtoRGBQUAD(cr));
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::SetPixelColor(long x,long y,RGBQUAD c, bool bSetAlpha)
{
if ((pDib==NULL)||(x<0)||(y<0)||
(x>=head.biWidth)||(y>=head.biHeight)) return;
if (head.biClrUsed)
SetPixelIndex(x,y,GetNearestIndex(c));
else {
BYTE* iDst = info.pImage + y*info.dwEffWidth + x*3;
*iDst++ = c.rgbBlue;
*iDst++ = c.rgbGreen;
*iDst = c.rgbRed;
#if CXIMAGE_SUPPORT_ALPHA
if (bSetAlpha) AlphaSet(x,y,c.rgbReserved);
#endif //CXIMAGE_SUPPORT_ALPHA
}
}
////////////////////////////////////////////////////////////////////////////////
BYTE CxImage::GetNearestIndex(RGBQUAD c)
{
if ((pDib==NULL)||(head.biClrUsed==0)) return 0;
// <RJ> check matching with the previous result
if (info.last_c_isvalid && (*(long*)&info.last_c == *(long*)&c)) return info.last_c_index;
info.last_c = c;
info.last_c_isvalid = true;
BYTE* iDst = (BYTE*)(pDib) + sizeof(BITMAPINFOHEADER);
long distance=200000;
int i,j = 0;
long k,l;
int m = (int)(head.biClrImportant==0 ? head.biClrUsed : head.biClrImportant);
for(i=0,l=0;i<m;i++,l+=sizeof(RGBQUAD)){
k = (iDst[l]-c.rgbBlue)*(iDst[l]-c.rgbBlue)+
(iDst[l+1]-c.rgbGreen)*(iDst[l+1]-c.rgbGreen)+
(iDst[l+2]-c.rgbRed)*(iDst[l+2]-c.rgbRed);
// k = abs(iDst[l]-c.rgbBlue)+abs(iDst[l+1]-c.rgbGreen)+abs(iDst[l+2]-c.rgbRed);
if (k==0){
j=i;
break;
}
if (k<distance){
distance=k;
j=i;
}
}
info.last_c_index = j;
return (BYTE)j;
}
////////////////////////////////////////////////////////////////////////////////
// swaps the blue and red components (for RGB images)
// > buffer: pointer to the pixels
// > lenght: number of bytes to swap. lenght may not exceed the scan line.
void CxImage::RGBtoBGR(BYTE *buffer, int length)
{
if (buffer && (head.biClrUsed==0)){
BYTE temp;
length = min(length,(int)info.dwEffWidth);
for (int i=0;i<length;i+=3){
temp = buffer[i]; buffer[i] = buffer[i+2]; buffer[i+2] = temp;
}
}
}
////////////////////////////////////////////////////////////////////////////////
RGBQUAD CxImage::RGBtoRGBQUAD(COLORREF cr)
{
RGBQUAD c;
c.rgbRed = GetRValue(cr); /* get R, G, and B out of DWORD */
c.rgbGreen = GetGValue(cr);
c.rgbBlue = GetBValue(cr);
c.rgbReserved=0;
return c;
}
////////////////////////////////////////////////////////////////////////////////
COLORREF CxImage::RGBQUADtoRGB (RGBQUAD c)
{
return RGB(c.rgbRed,c.rgbGreen,c.rgbBlue);
}
////////////////////////////////////////////////////////////////////////////////
bool CxImage::GetPaletteColor(BYTE i, BYTE* r, BYTE* g, BYTE* b)
{
RGBQUAD* ppal=GetPalette();
if (ppal) {
*r = ppal[i].rgbRed;
*g = ppal[i].rgbGreen;
*b = ppal[i].rgbBlue;
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -