//@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; }
//! Checks whether the mode is enabled. ILAPI ILboolean ILAPIENTRY ilIsEnabled(ILenum Mode) { return il2IsEnabled(Mode); }