www.pudn.com > cximage602_full.rar > ximalpha.cpp
// xImalpha.cpp : Alpha channel functions
/* 07/08/2001 v1.00 - Davide Pizzolato - www.xdp.it
* CxImage version 6.0.0 02/Feb/2008
*/
#include "ximage.h"
#if CXIMAGE_SUPPORT_ALPHA
////////////////////////////////////////////////////////////////////////////////
/**
* \sa AlphaSetMax
*/
BYTE CxImage::AlphaGetMax() const
{
return info.nAlphaMax;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Sets global Alpha (opacity) value applied to the whole image,
* valid only for painting functions.
* \param nAlphaMax: can be from 0 to 255
*/
void CxImage::AlphaSetMax(BYTE nAlphaMax)
{
info.nAlphaMax=nAlphaMax;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Checks if the image has a valid alpha channel.
*/
bool CxImage::AlphaIsValid()
{
return pAlpha!=0;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Enables the alpha palette, so the Draw() function changes its behavior.
*/
void CxImage::AlphaPaletteEnable(bool enable)
{
info.bAlphaPaletteEnabled=enable;
}
////////////////////////////////////////////////////////////////////////////////
/**
* True if the alpha palette is enabled for painting.
*/
bool CxImage::AlphaPaletteIsEnabled()
{
return info.bAlphaPaletteEnabled;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Sets the alpha channel to full transparent. AlphaSet(0) has the same effect
*/
void CxImage::AlphaClear()
{
if (pAlpha) memset(pAlpha,0,head.biWidth * head.biHeight);
}
////////////////////////////////////////////////////////////////////////////////
/**
* Sets the alpha level for the whole image.
* \param level : from 0 (transparent) to 255 (opaque)
*/
void CxImage::AlphaSet(BYTE level)
{
if (pAlpha) memset(pAlpha,level,head.biWidth * head.biHeight);
}
////////////////////////////////////////////////////////////////////////////////
/**
* Allocates an empty (opaque) alpha channel.
*/
bool CxImage::AlphaCreate()
{
if (pAlpha==NULL) {
pAlpha = (BYTE*)malloc(head.biWidth * head.biHeight);
if (pAlpha) memset(pAlpha,255,head.biWidth * head.biHeight);
}
return (pAlpha!=0);
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::AlphaDelete()
{
if (pAlpha) { free(pAlpha); pAlpha=0; }
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::AlphaInvert()
{
if (pAlpha) {
BYTE *iSrc=pAlpha;
long n=head.biHeight*head.biWidth;
for(long i=0; i < n; i++){
*iSrc=(BYTE)~(*(iSrc));
iSrc++;
}
}
}
////////////////////////////////////////////////////////////////////////////////
/**
* Imports an existing alpa channel from another image with the same width and height.
*/
bool CxImage::AlphaCopy(CxImage &from)
{
if (from.pAlpha == NULL || head.biWidth != from.head.biWidth || head.biHeight != from.head.biHeight) return false;
if (pAlpha==NULL) pAlpha = (BYTE*)malloc(head.biWidth * head.biHeight);
if (pAlpha==NULL) return false;
memcpy(pAlpha,from.pAlpha,head.biWidth * head.biHeight);
info.nAlphaMax=from.info.nAlphaMax;
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Creates the alpha channel from a gray scale image.
*/
bool CxImage::AlphaSet(CxImage &from)
{
if (!from.IsGrayScale() || head.biWidth != from.head.biWidth || head.biHeight != from.head.biHeight) return false;
if (pAlpha==NULL) pAlpha = (BYTE*)malloc(head.biWidth * head.biHeight);
BYTE* src = from.info.pImage;
BYTE* dst = pAlpha;
if (src==NULL || dst==NULL) return false;
for (long y=0; y>8);
c.rgbGreen = (BYTE)((c.rgbGreen * a + a1 * info.nBkgndColor.rgbGreen)>>8);
c.rgbRed = (BYTE)((c.rgbRed * a + a1 * info.nBkgndColor.rgbRed)>>8);
BlindSetPixelColor(x,y,c);
}
}
AlphaDelete();
} else {
CxImage tmp(head.biWidth,head.biHeight,24);
if (!tmp.IsValid()){
strcpy(info.szLastError,tmp.GetLastError());
return;
}
for(long y=0; y>8);
c.rgbGreen = (BYTE)((c.rgbGreen * a + a1 * info.nBkgndColor.rgbGreen)>>8);
c.rgbRed = (BYTE)((c.rgbRed * a + a1 * info.nBkgndColor.rgbRed)>>8);
tmp.BlindSetPixelColor(x,y,c);
}
}
Transfer(tmp);
}
return;
}
////////////////////////////////////////////////////////////////////////////////
bool CxImage::AlphaFlip()
{
if (!pAlpha) return false;
BYTE *buff = (BYTE*)malloc(head.biWidth);
if (!buff) return false;
BYTE *iSrc,*iDst;
iSrc = pAlpha + (head.biHeight-1)*head.biWidth;
iDst = pAlpha;
for (long i=0; i<(head.biHeight/2); ++i)
{
memcpy(buff, iSrc, head.biWidth);
memcpy(iSrc, iDst, head.biWidth);
memcpy(iDst, buff, head.biWidth);
iSrc-=head.biWidth;
iDst+=head.biWidth;
}
free(buff);
return true;
}
////////////////////////////////////////////////////////////////////////////////
bool CxImage::AlphaMirror()
{
if (!pAlpha) return false;
BYTE* pAlpha2 = (BYTE*)malloc(head.biWidth * head.biHeight);
if (!pAlpha2) return false;
BYTE *iSrc,*iDst;
long wdt=head.biWidth-1;
iSrc=pAlpha + wdt;
iDst=pAlpha2;
for(long y=0; y < head.biHeight; y++){
for(long x=0; x <= wdt; x++)
*(iDst+x)=*(iSrc-x);
iSrc+=head.biWidth;
iDst+=head.biWidth;
}
free(pAlpha);
pAlpha=pAlpha2;
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Exports the alpha channel in a 8bpp grayscale image.
*/
bool CxImage::AlphaSplit(CxImage *dest)
{
if (!pAlpha || !dest) return false;
CxImage tmp(head.biWidth,head.biHeight,8);
if (!tmp.IsValid()){
strcpy(info.szLastError,tmp.GetLastError());
return false;
}
for(long y=0; yTransfer(tmp);
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Exports the alpha palette channel in a 8bpp grayscale image.
*/
bool CxImage::AlphaPaletteSplit(CxImage *dest)
{
if (!AlphaPaletteIsValid() || !dest) return false;
CxImage tmp(head.biWidth,head.biHeight,8);
if (!tmp.IsValid()){
strcpy(info.szLastError,tmp.GetLastError());
return false;
}
for(long y=0; yTransfer(tmp);
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Merge in the alpha layer the transparent color mask
* (previously set with SetTransColor or SetTransIndex)
*/
bool CxImage::AlphaFromTransparency()
{
if (!IsValid() || !IsTransparent())
return false;
AlphaCreate();
for(long y=0; y