Пример #1
0
//@NEXT DestX,DestY,DestZ must be set to ILuint
ILboolean ILAPIENTRY il2Blit(ILimage* aSource, ILimage* aTarget, ILint DestX,  ILint DestY,   ILint DestZ, 
	ILuint SrcX,  ILuint SrcY,   ILuint SrcZ, ILuint Width, ILuint Height, ILuint Depth)
{
	ILuint 		x, y, z, ConvBps, ConvSizePlane;
	ILubyte 	*Converted;
	ILuint		DestName = ilGetCurName();
	ILuint		c;
	ILuint		StartX, StartY, StartZ;
	ILboolean	DestFlipped = IL_FALSE;
	ILboolean	DoAlphaBlend = IL_FALSE;
	ILubyte 	*SrcTemp;
	ILfloat		ResultAlpha;

	// Check if source and target images really exist
	if (aSource == NULL || aTarget == NULL) {
		il2SetError(IL_ILLEGAL_OPERATION);
		return IL_FALSE;
	}
	
	// set the destination image to upper left origin
	if (aTarget->Origin == IL_ORIGIN_LOWER_LEFT) {  // Dest
		DestFlipped = IL_TRUE;
		ilFlipImage(aTarget);
	}

	//determine alpha support
	DoAlphaBlend = il2IsEnabled(IL_BLIT_BLEND);

	//@TODO test if coordinates are inside the images (hard limit for source)
	
	// set the source image to upper left origin
	if (aSource->Origin == IL_ORIGIN_LOWER_LEFT)
	{
		SrcTemp = iGetFlipped(aSource);
		if (SrcTemp == NULL)
		{
			if (DestFlipped)
				ilFlipImage(aTarget);
			return IL_FALSE;
		}
	}
	else
	{
		SrcTemp = aSource->Data;
	}
	
	// convert source image to match the destination image type and format
	Converted = (ILubyte*)ilConvertBuffer(aSource->SizeOfData, aSource->Format, aTarget->Format, 
		aSource->Type, aTarget->Type, NULL, SrcTemp);
	if (Converted == NULL)
		return IL_FALSE;
	
	ConvBps 	  = aTarget->Bpp * aSource->Width;
	ConvSizePlane = ConvBps   * aSource->Height;
	
	//@NEXT in next version this would have to be removed since Dest* will be unsigned
	StartX = DestX >= 0 ? 0 : -DestX;
	StartY = DestY >= 0 ? 0 : -DestY;
	StartZ = DestZ >= 0 ? 0 : -DestZ;
	
	// Limit the copy of data inside of the destination image
	if (Width  + DestX > aTarget->Width)  Width  = aTarget->Width  - DestX;
	if (Height + DestY > aTarget->Height) Height = aTarget->Height - DestY;
	if (Depth  + DestZ > aTarget->Depth)  Depth  = aTarget->Depth  - DestZ;
	
	//@TODO: non funziona con rgba
	if (aSource->Format == IL_RGBA || aSource->Format == IL_BGRA || aSource->Format == IL_LUMINANCE_ALPHA) {
		const ILuint bpp_without_alpha = aTarget->Bpp - 1;
		for (z = 0; z < Depth; z++) {
			for (y = 0; y < Height; y++) {
				for (x = 0; x < Width; x++) {
					const ILuint  SrcIndex  = (z+SrcZ)*ConvSizePlane + (y+SrcY)*ConvBps + (x+SrcX)*aTarget->Bpp;
					const ILuint  DestIndex = (z+DestZ)*aTarget->SizeOfPlane + (y+DestY)*aTarget->Bps + (x+DestX)*aTarget->Bpp;
					const ILuint  AlphaIdx = SrcIndex + bpp_without_alpha;
					ILfloat FrontAlpha = 0; // foreground opacity
					ILfloat BackAlpha = 0;	// background opacity
					
					switch (aTarget->Type)
					{
						case IL_BYTE:
						case IL_UNSIGNED_BYTE:
							FrontAlpha = Converted[AlphaIdx]/((float)IL_MAX_UNSIGNED_BYTE);
							BackAlpha = aTarget->Data[AlphaIdx]/((float)IL_MAX_UNSIGNED_BYTE);
							break;
						case IL_SHORT:
						case IL_UNSIGNED_SHORT:
							FrontAlpha = ((ILshort*)Converted)[AlphaIdx]/((float)IL_MAX_UNSIGNED_SHORT);
							BackAlpha = ((ILshort*)aTarget->Data)[AlphaIdx]/((float)IL_MAX_UNSIGNED_SHORT);
							break;
						case IL_INT:
						case IL_UNSIGNED_INT:
							FrontAlpha = ((ILint*)Converted)[AlphaIdx]/((float)IL_MAX_UNSIGNED_INT);
							BackAlpha = ((ILint*)aTarget->Data)[AlphaIdx]/((float)IL_MAX_UNSIGNED_INT);
							break;
						case IL_FLOAT:
							FrontAlpha = ((ILfloat*)Converted)[AlphaIdx];
							BackAlpha = ((ILfloat*)aTarget->Data)[AlphaIdx];
							break;
						case IL_DOUBLE:
							FrontAlpha = (ILfloat)(((ILdouble*)Converted)[AlphaIdx]);
							BackAlpha = (ILfloat)(((ILdouble*)aTarget->Data)[AlphaIdx]);
							break;
					}
					
					// In case of Alpha channel, the data is blended.
					// Computes composite Alpha
					if (DoAlphaBlend)
					{
						ResultAlpha = FrontAlpha + (1.0f - FrontAlpha) * BackAlpha;
						for (c = 0; c < bpp_without_alpha; c++)
						{
							aTarget->Data[DestIndex + c] = (ILubyte)( 0.5f + 
								(Converted[SrcIndex + c] * FrontAlpha + 
								(1.0f - FrontAlpha) * aTarget->Data[DestIndex + c] * BackAlpha) 
								/ ResultAlpha);
						}
						aTarget->Data[AlphaIdx] = (ILubyte)(0.5f + ResultAlpha * (float)IL_MAX_UNSIGNED_BYTE);
					}
					else {
						for (c = 0; c < aTarget->Bpp; c++)
						{
							aTarget->Data[DestIndex + c] = (ILubyte)(Converted[SrcIndex + c]);
						}
					}
				}
			}
		}
	} else {
		for( z = 0; z < Depth; z++ ) {
			for( y = 0; y < Height; y++ ) {
				for( x = 0; x < Width; x++ ) {
					for( c = 0; c < aTarget->Bpp; c++ ) {
						aTarget->Data[(z+DestZ)*aTarget->SizeOfPlane + (y+DestY)*aTarget->Bps + (x+DestX)*aTarget->Bpp + c] =
						 Converted[(z+SrcZ)*ConvSizePlane + (y+SrcY)*ConvBps + (x+SrcX)*aTarget->Bpp + c];
					}
				}
			}
		}
	}
	
	if (SrcTemp != aSource->Data)
		ifree(SrcTemp);
	
	if (DestFlipped)
		ilFlipImage(aTarget);
	
	ifree(Converted);
	
	return IL_TRUE;
}
Пример #2
0
//! Checks whether the mode is enabled.
ILAPI ILboolean ILAPIENTRY ilIsEnabled(ILenum Mode)
{
	return il2IsEnabled(Mode);
}