Beispiel #1
0
/**
 * Blends the alpha channel and the alpha palette with the pixels. The result is a 24 bit image.
 * The background color can be selected using SetTransColor().
 */
void CxImage::AlphaStrip()
{
	bool bAlphaPaletteIsValid = AlphaPaletteIsValid();
	bool bAlphaIsValid = AlphaIsValid();
	if (!(bAlphaIsValid || bAlphaPaletteIsValid)) return;
	RGBQUAD c;
	long a, a1;
	if (head.biBitCount==24){
		for(long y=0; y<head.biHeight; y++){
			for(long x=0; x<head.biWidth; x++){
				c = BlindGetPixelColor(x,y);
				if (bAlphaIsValid) a=(BlindAlphaGet(x,y)*info.nAlphaMax)/255; else a=info.nAlphaMax;
				a1 = 256-a;
				c.rgbBlue = (BYTE)((c.rgbBlue * a + a1 * info.nBkgndColor.rgbBlue)>>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 {
Beispiel #2
0
/**
 * Blends the alpha channel and the alpha palette with the pixels. The result is a 24 bit image.
 * The background color can be selected using SetTransColor().
 */
void CxImage::AlphaStrip()
{
	bool bAlphaPaletteIsValid = AlphaPaletteIsValid();
	bool bAlphaIsValid = AlphaIsValid();
	if (!(bAlphaIsValid || bAlphaPaletteIsValid)) return;
	RGBQUAD c;
	long a, a1;
	if (head.biBitCount==24){
		for(long y=0; y<head.biHeight; y++){
			for(long x=0; x<head.biWidth; x++){
				c=GetPixelColor(x,y);
				if (bAlphaIsValid) a=(AlphaGet(x,y)*info.nAlphaMax)/255; else a=info.nAlphaMax;
				a1 = 255-a;
				c.rgbBlue = (BYTE)((c.rgbBlue * a + a1 * info.nBkgndColor.rgbBlue)/255);
				c.rgbGreen = (BYTE)((c.rgbGreen * a + a1 * info.nBkgndColor.rgbGreen)/255);
				c.rgbRed = (BYTE)((c.rgbRed * a + a1 * info.nBkgndColor.rgbRed)/255);
				SetPixelColor(x,y,c);
			}
		}
		AlphaDelete();
	} else {
		CxImage tmp(head.biWidth,head.biHeight,24);
		if (!tmp.IsValid()) return;
		for(long y=0; y<head.biHeight; y++){
			for(long x=0; x<head.biWidth; x++){
				c=GetPixelColor(x,y);
				if (bAlphaIsValid) a=(AlphaGet(x,y)*info.nAlphaMax)/255; else a=info.nAlphaMax;
				if (bAlphaPaletteIsValid) a=(c.rgbReserved*a)/255;
				a1 = 255-a;
				c.rgbBlue = (BYTE)((c.rgbBlue * a + a1 * info.nBkgndColor.rgbBlue)/255);
				c.rgbGreen = (BYTE)((c.rgbGreen * a + a1 * info.nBkgndColor.rgbGreen)/255);
				c.rgbRed = (BYTE)((c.rgbRed * a + a1 * info.nBkgndColor.rgbRed)/255);
				tmp.SetPixelColor(x,y,c);
			}
		}
		Transfer(tmp);
	}
	return;
}
Beispiel #3
0
bool CxImageICO::Decode(CxFile *hFile)
{
	if (hFile==NULL) return false;

	DWORD off = hFile->Tell(); //<yuandi>
	int	page=info.nFrame;	//internal icon structure indexes

	// read the first part of the header
	ICONHEADER icon_header;
	hFile->Read(&icon_header,sizeof(ICONHEADER),1);

	icon_header.idType = my_ntohs(icon_header.idType);
	icon_header.idCount = my_ntohs(icon_header.idCount);

	// check if it's an icon or a cursor
	if ((icon_header.idReserved == 0) && ((icon_header.idType == 1)||(icon_header.idType == 2))) {

		info.nNumFrames = icon_header.idCount;

		// load the icon descriptions
		ICONDIRENTRY *icon_list = (ICONDIRENTRY *)malloc(icon_header.idCount * sizeof(ICONDIRENTRY));
		int c;
		for (c = 0; c < icon_header.idCount; c++) {
			hFile->Read(icon_list + c, sizeof(ICONDIRENTRY), 1);

			icon_list[c].wPlanes = my_ntohs(icon_list[c].wPlanes);
			icon_list[c].wBitCount = my_ntohs(icon_list[c].wBitCount);
			icon_list[c].dwBytesInRes = my_ntohl(icon_list[c].dwBytesInRes);
			icon_list[c].dwImageOffset = my_ntohl(icon_list[c].dwImageOffset);
		}
		
		if ((page>=0)&&(page<icon_header.idCount)){

			if (info.nEscape == -1) {
				// Return output dimensions only
				head.biWidth = icon_list[page].bWidth;
				head.biHeight = icon_list[page].bHeight;
#if CXIMAGE_SUPPORT_PNG
				if (head.biWidth==0 && head.biHeight==0)
				{	// Vista icon support
					hFile->Seek(off + icon_list[page].dwImageOffset, SEEK_SET);
					CxImage png;
					png.SetEscape(-1);
					if (png.Decode(hFile,CXIMAGE_FORMAT_PNG)){
						Transfer(png);
						info.nNumFrames = icon_header.idCount;
					}
				}
#endif //CXIMAGE_SUPPORT_PNG
				free(icon_list);
				info.dwType = CXIMAGE_FORMAT_ICO;
				return true;
			}

			// get the bit count for the colors in the icon <CoreyRLucier>
			BITMAPINFOHEADER bih;
			hFile->Seek(off + icon_list[page].dwImageOffset, SEEK_SET);

			if (icon_list[page].bWidth==0 && icon_list[page].bHeight==0)
			{	// Vista icon support
#if CXIMAGE_SUPPORT_PNG
				CxImage png;
				if (png.Decode(hFile,CXIMAGE_FORMAT_PNG)){
					Transfer(png);
					info.nNumFrames = icon_header.idCount;
				}
				SetType(CXIMAGE_FORMAT_ICO);
#endif //CXIMAGE_SUPPORT_PNG
			}
			else
			{	// standard icon
				hFile->Read(&bih,sizeof(BITMAPINFOHEADER),1);

				bihtoh(&bih);

				c = bih.biBitCount;

				// allocate memory for one icon
				Create(icon_list[page].bWidth,icon_list[page].bHeight, c, CXIMAGE_FORMAT_ICO);	//image creation

				// read the palette
				RGBQUAD pal[256];
				if (bih.biClrUsed)
					hFile->Read(pal,bih.biClrUsed*sizeof(RGBQUAD), 1);
				else
					hFile->Read(pal,head.biClrUsed*sizeof(RGBQUAD), 1);

				SetPalette(pal,head.biClrUsed);	//palette assign

				//read the icon
				if (c<=24){
					hFile->Read(info.pImage, head.biSizeImage, 1);
				} else { // 32 bit icon
					BYTE* buf=(BYTE*)malloc(4*head.biHeight*head.biWidth);
					BYTE* src = buf;
					hFile->Read(buf, 4*head.biHeight*head.biWidth, 1);
#if CXIMAGE_SUPPORT_ALPHA
					if (!AlphaIsValid()) AlphaCreate();
#endif //CXIMAGE_SUPPORT_ALPHA
					for (long y = 0; y < head.biHeight; y++) {
						BYTE* dst = GetBits(y);
						for(long x=0;x<head.biWidth;x++){
							*dst++=src[0];
							*dst++=src[1];
							*dst++=src[2];
#if CXIMAGE_SUPPORT_ALPHA
							AlphaSet(x,y,src[3]);
#endif //CXIMAGE_SUPPORT_ALPHA
							src+=4;
						}
					}
					free(buf);
				}
				// apply the AND and XOR masks
				int maskwdt = ((head.biWidth+31) / 32) * 4;	//line width of AND mask (always 1 Bpp)
				int masksize = head.biHeight * maskwdt;				//size of mask
				BYTE *mask = (BYTE *)malloc(masksize);
				if (hFile->Read(mask, masksize, 1)){

					bool bGoodMask=false;
					for (int im=0;im<masksize;im++){
						if (mask[im]!=255){
							bGoodMask=true;
							break;
						}
					}

					if (bGoodMask && c != 32){
#if CXIMAGE_SUPPORT_ALPHA
						bool bNeedAlpha = false;
						if (!AlphaIsValid()){
							AlphaCreate();
						} else { 
							bNeedAlpha=true; //32bit icon
						}
						int x,y;
						for (y = 0; y < head.biHeight; y++) {
							for (x = 0; x < head.biWidth; x++) {
								if (((mask[y*maskwdt+(x>>3)]>>(7-x%8))&0x01)){
									AlphaSet(x,y,0);
									bNeedAlpha=true;
								}
							}
						}
						if (!bNeedAlpha) AlphaDelete();
#endif //CXIMAGE_SUPPORT_ALPHA

						//check if there is only one transparent color
						RGBQUAD cc,ct;
						long* pcc = (long*)&cc;
						long* pct = (long*)&ct;
						int nTransColors=0;
						int nTransIndex=0;
						for (y = 0; y < head.biHeight; y++){
							for (x = 0; x < head.biWidth; x++){
								if (((mask[y*maskwdt+(x>>3)] >> (7-x%8)) & 0x01)){
									cc = GetPixelColor(x,y,false);
									if (nTransColors==0){
										nTransIndex = GetPixelIndex(x,y);
										nTransColors++;
										ct = cc;
									} else {
										if (*pct!=*pcc){
											nTransColors++;
										}
									}
								}
							}
						}
						if (nTransColors==1){
							SetTransColor(ct);
							SetTransIndex(nTransIndex);
#if CXIMAGE_SUPPORT_ALPHA
							AlphaDelete(); //because we have a unique transparent color in the image
#endif //CXIMAGE_SUPPORT_ALPHA
						}

						// <vho> - Transparency support w/o Alpha support
						if (c <= 8){ // only for icons with less than 256 colors (XP icons need alpha).
							  
							// find a color index, which is not used in the image
							// it is almost sure to find one, bcs. nobody uses all possible colors for an icon

							BYTE colorsUsed[256];
							memset(colorsUsed, 0, sizeof(colorsUsed));

							for (y = 0; y < head.biHeight; y++){
								for (x = 0; x < head.biWidth; x++){
									colorsUsed[BlindGetPixelIndex(x,y)] = 1;
								}
							}

							int iTransIdx = -1;
							for (x = (int)(head.biClrUsed-1); x>=0 ; x--){
								if (colorsUsed[x] == 0){
									iTransIdx = x; // this one is not in use. we may use it as transparent color
									break;
								}
							}

							// Go thru image and set unused color as transparent index if needed
							if (iTransIdx >= 0){
								bool bNeedTrans = false;
								for (y = 0; y < head.biHeight; y++){
									for (x = 0; x < head.biWidth; x++){
										// AND mask (Each Byte represents 8 Pixels)
										if (((mask[y*maskwdt+(x>>3)] >> (7-x%8)) & 0x01)){
											// AND mask is set (!=0). This is a transparent part
											SetPixelIndex(x, y, (BYTE)iTransIdx);
											bNeedTrans = true;
										}
									}
								}
								// set transparent index if needed
								if (bNeedTrans)	SetTransIndex(iTransIdx);
#if CXIMAGE_SUPPORT_ALPHA
								AlphaDelete(); //because we have a transparent color in the palette
#endif //CXIMAGE_SUPPORT_ALPHA
							}
						}
					} else if(c != 32){
bool CxImageICO::Decode(CxFile *hFile)
{
	if (hFile==NULL) return false;

	DWORD off = hFile->Tell(); //<yuandi>
	int	page=info.nFrame;	//internal icon structure indexes

	// read the first part of the header
	ICONHEADER icon_header;
	hFile->Read(&icon_header,sizeof(ICONHEADER),1);
	// check if it's an icon
	if ((icon_header.idReserved == 0) && (icon_header.idType == 1)) {

		info.nNumFrames = icon_header.idCount;

		// load the icon descriptions
		ICONDIRENTRY *icon_list = (ICONDIRENTRY *)malloc(icon_header.idCount * sizeof(ICONDIRENTRY));
		int c;
		for (c = 0; c < icon_header.idCount; c++)
			hFile->Read(icon_list + c, sizeof(ICONDIRENTRY), 1);
		
		if ((info.nFrame>=0)&&(info.nFrame<icon_header.idCount)){

			// get the bit count for the colors in the icon <CoreyRLucier>
			BITMAPINFOHEADER bih;
			hFile->Seek(off + icon_list[page].dwImageOffset, SEEK_SET);
			hFile->Read(&bih,sizeof(BITMAPINFOHEADER),1);
			c = bih.biBitCount;

			// allocate memory for one icon
			Create(icon_list[page].bWidth,icon_list[page].bHeight, c, CXIMAGE_FORMAT_ICO);	//image creation

			// read the palette
			RGBQUAD pal[256];
			hFile->Read(pal,head.biClrUsed*sizeof(RGBQUAD), 1);
			SetPalette(pal,head.biClrUsed);	//palette assign

			//read the icon
			if (c<=24){
				hFile->Read(info.pImage, head.biSizeImage, 1);
			} else { // 32 bit icon
				BYTE* dst = info.pImage;
				BYTE* buf=(BYTE*)malloc(4*head.biHeight*head.biWidth);
				BYTE* src = buf;
				hFile->Read(buf, 4*head.biHeight*head.biWidth, 1);
#if CXIMAGE_SUPPORT_ALPHA
				if (!AlphaIsValid()) AlphaCreate();
#endif //CXIMAGE_SUPPORT_ALPHA
				for (long y = 0; y < head.biHeight; y++) {
					for(long x=0;x<head.biWidth;x++){
						*dst++=src[0];
						*dst++=src[1];
						*dst++=src[2];
#if CXIMAGE_SUPPORT_ALPHA
						AlphaSet(x,y,src[3]);
#endif //CXIMAGE_SUPPORT_ALPHA
						src+=4;
					}
				}
				free(buf);
			}
			// apply the AND and XOR masks
			int maskwdt = ((head.biWidth+31) / 32) * 4;	//line width of AND mask (always 1 Bpp)
			int masksize = head.biHeight * maskwdt;				//size of mask
			BYTE *mask = (BYTE *)malloc(masksize);
			if (hFile->Read(mask, masksize, 1)){

#if CXIMAGE_SUPPORT_ALPHA
				bool bNeedAlpha = false;
				if (!AlphaIsValid()){
					AlphaCreate();
					AlphaSet(255);
				} else { 
					bNeedAlpha=true; //32bit icon
				}
				for (int y = 0; y < head.biHeight; y++) {
					for (int x = 0; x < head.biWidth; x++) {
						if (((mask[y*maskwdt+(x>>3)]>>(7-x%8))&0x01)){
							AlphaSet(x,y,0);
							bNeedAlpha=true;
						}
					}
				}
				if (!bNeedAlpha) AlphaDelete();
#endif //CXIMAGE_SUPPORT_ALPHA

				if (c==24){ //check if there is only one transparent color
					RGBQUAD cc,ct;
					long* pcc = (long*)&cc;
					long* pct = (long*)&ct;
					int nTransColors=0;
					for (int y = 0; y < head.biHeight; y++){
						for (int x = 0; x < head.biWidth; x++){
							if (((mask[y*maskwdt+(x>>3)] >> (7-x%8)) & 0x01)){
								cc = GetPixelColor(x,y);
								if (nTransColors==0){
									nTransColors++;
									ct = cc;
								} else {
									if (*pct!=*pcc){
										nTransColors++;
									}
								}
							}
						}
					}
					if (nTransColors==1){
						SetTransColor(ct);
						SetTransIndex(0);
#if CXIMAGE_SUPPORT_ALPHA
						AlphaDelete(); //because we have a unique transparent color in the image
#endif //CXIMAGE_SUPPORT_ALPHA
					}
				}
Beispiel #5
0
void CxImage::AlphaCreate()
{
	AlphaDelete();
	pAlpha = (BYTE*)calloc(head.biWidth * head.biHeight, 1);
}