ILAPI void ILAPIENTRY il2SetPixels(ILimage* image, ILint XOff, ILint YOff, ILint ZOff, ILuint Width, ILuint Height, ILuint Depth, ILenum Format, ILenum Type, void *Data) { void *Converted; if (image == NULL) { il2SetError(IL_ILLEGAL_OPERATION); return; } if (Data == NULL) { il2SetError(IL_INVALID_PARAM); return; } if (Format == image->Format && Type == image->Type) { Converted = (void*)Data; } else { Converted = ilConvertBuffer(Width * Height * Depth * ilGetBppFormat(Format) * ilGetBpcType(Type), Format, image->Format, Type, image->Type, NULL, Data); if (!Converted) return; } if (YOff + Height <= 1) { ilSetPixels1D(image, XOff, Width, Converted); } else if (ZOff + Depth <= 1) { ilSetPixels2D(image, XOff, YOff, Width, Height, Converted); } else { ilSetPixels3D(image, XOff, YOff, ZOff, Width, Height, Depth, Converted); } if (Format == image->Format && Type == image->Type) { return; } if (Converted != Data) ifree(Converted); return; }
ILboolean ILAPIENTRY ilBlit(ILuint Source, ILint DestX, ILint DestY, ILint DestZ, ILuint SrcX, ILuint SrcY, ILuint SrcZ, ILuint Width, ILuint Height, ILuint Depth) { register ILuint x, y, z, SrcIndex, DestIndex, ConvBps, ConvSizePlane; ILimage *Dest; ILubyte *Converted; ILuint DestName = ilGetCurName(); ILint c; ILfloat FrontPer, BackPer; ILenum DestOrigin, SrcOrigin; ILuint StartX, StartY, StartZ, AlphaOff; ILboolean DestFlipped = IL_FALSE; ILubyte *SrcTemp; if (DestName == 0 || iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } if (iCurImage->Origin == IL_ORIGIN_LOWER_LEFT) { // Dest DestFlipped = IL_TRUE; ilFlipImage(); } Dest = iCurImage; DestOrigin = iCurImage->Origin; ilBindImage(Source); SrcOrigin = iCurImage->Origin; if (iCurImage->Origin == IL_ORIGIN_LOWER_LEFT) { SrcTemp = iGetFlipped(iCurImage); if (SrcTemp == NULL) { ilBindImage(DestName); if (DestFlipped) ilFlipImage(); return IL_FALSE; } } else { SrcTemp = iCurImage->Data; } if (Dest == NULL || iCurImage == NULL) { ilSetError(IL_INVALID_PARAM); return IL_FALSE; } Converted = ilConvertBuffer(iCurImage->SizeOfData, iCurImage->Format, Dest->Format, iCurImage->Type, Dest->Type, SrcTemp); if (Converted == NULL) return IL_FALSE; ConvBps = Dest->Bpp * iCurImage->Width; ConvSizePlane = ConvBps * iCurImage->Height; StartX = DestX >= 0 ? 0 : -DestX; StartY = DestY >= 0 ? 0 : -DestY; StartZ = DestZ >= 0 ? 0 : -DestZ; Width = Width + SrcX < Dest->Width ? Width + SrcX : Dest->Width; Height = Height + SrcY < Dest->Height ? Height + SrcY : Dest->Height; Depth = Depth + SrcZ < Dest->Depth ? Depth + SrcZ : Dest->Depth; if (iCurImage->Format == IL_RGBA || iCurImage->Format == IL_BGRA || iCurImage->Format == IL_LUMINANCE_ALPHA) { if (iCurImage->Format == IL_LUMINANCE_ALPHA) AlphaOff = 1; else AlphaOff = 3; for (z = StartZ; z < Depth && z + DestZ < Dest->Depth; z++) { for (y = StartY; y < Height && y + DestY < Dest->Height; y++) { for (x = StartX; x < Width && x + DestX < Dest->Width; x++) { SrcIndex = (z + SrcZ) * ConvSizePlane + (y + SrcY) * ConvBps + (x + SrcX) * Dest->Bpp; DestIndex = (z + DestZ) * Dest->SizeOfPlane + (y + DestY) * Dest->Bps + (x + DestX) * Dest->Bpp; // Use the original alpha FrontPer = iCurImage->Data[(z + SrcZ) * iCurImage->SizeOfPlane + (y + SrcY) * iCurImage->Bps + (x + SrcX) * iCurImage->Bpp + 3] / 255.0f; BackPer = 1.0f - FrontPer; for (c = 0; c < Dest->Bpp - 1; c++) { Dest->Data[DestIndex + c] = (ILubyte)(Converted[SrcIndex + c] * FrontPer + Dest->Data[DestIndex + c] * BackPer); } // Keep the original alpha. //Dest->Data[DestIndex + c + 1] = Dest->Data[DestIndex + c + 1]; } } } } else { for (z = StartZ; z < Depth && z + DestZ < Dest->Depth; z++) { for (y = StartY; y < Height && y + DestY < Dest->Height; y++) { for (x = StartX; x < Width && x + DestX < Dest->Width; x++) { for (c = 0; c < Dest->Bpp; c++) { Dest->Data[(z + DestZ) * Dest->SizeOfPlane + (y + DestY) * Dest->Bps + (x + DestX) * Dest->Bpp + c] = Converted[(z + SrcZ) * ConvSizePlane + (y + SrcY) * ConvBps + (x + SrcX) * Dest->Bpp + c]; } } } } } if (SrcTemp != iCurImage->Data) ifree(SrcTemp); ilBindImage(DestName); if (DestFlipped) ilFlipImage(); ifree(Converted); return IL_TRUE; }
//! Overlays the image found in Src on top of the current bound image at the coords specified. ILboolean ILAPIENTRY ilOverlayImage(ILuint Source, ILint XCoord, ILint YCoord, ILint ZCoord) { ILuint x, y, z, SrcIndex, DestIndex, ConvBps, ConvSizePlane; ILint c; ILimage *Dest;//, *Src; ILubyte *Converted; ILuint DestName = ilGetCurName(); ILfloat FrontPer, BackPer; ILenum DestOrigin, SrcOrigin; ILuint StartX, StartY, StartZ, AlphaOff; ILubyte *SrcTemp = NULL; ILboolean DestFlipped = IL_FALSE; if (DestName == 0 || iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } if (iCurImage->Origin == IL_ORIGIN_LOWER_LEFT) { // Dest DestFlipped = IL_TRUE; ilFlipImage(); } Dest = iCurImage; DestOrigin = iCurImage->Origin; ilBindImage(Source); SrcOrigin = iCurImage->Origin; if (iCurImage->Origin == IL_ORIGIN_LOWER_LEFT) { SrcTemp = iGetFlipped(iCurImage); if (SrcTemp == NULL) { ilBindImage(DestName); if (DestFlipped) ilFlipImage(); return IL_FALSE; } } else { SrcTemp = iCurImage->Data; } if (Dest == NULL || iCurImage == NULL) { ilSetError(IL_INVALID_PARAM); return IL_FALSE; } Converted = ilConvertBuffer(iCurImage->SizeOfData, iCurImage->Format, Dest->Format, iCurImage->Type, Dest->Type, SrcTemp); if (Converted == NULL) return IL_FALSE; ConvBps = Dest->Bpp * iCurImage->Width; ConvSizePlane = ConvBps * iCurImage->Height; StartX = XCoord >= 0 ? 0 : -XCoord; StartY = YCoord >= 0 ? 0 : -YCoord; StartZ = ZCoord >= 0 ? 0 : -ZCoord; if (iCurImage->Format == IL_RGBA || iCurImage->Format == IL_BGRA || iCurImage->Format == IL_LUMINANCE_ALPHA) { if (iCurImage->Format == IL_LUMINANCE_ALPHA) AlphaOff = 1; else AlphaOff = 3; for (z = StartZ; z < iCurImage->Depth && (ILint)z + ZCoord < (ILint)Dest->Depth; z++) { for (y = StartY; y < iCurImage->Height && (ILint)y + YCoord < (ILint)Dest->Height; y++) { for (x = StartX; x < iCurImage->Width && (ILint)x + XCoord < (ILint)Dest->Width; x++) { SrcIndex = z * ConvSizePlane + y * ConvBps + x * Dest->Bpp; DestIndex = (z + ZCoord) * Dest->SizeOfPlane + (y + YCoord) * Dest->Bps + (x + XCoord) * Dest->Bpp; FrontPer = iCurImage->Data[z * iCurImage->SizeOfPlane + y * iCurImage->Bps + x * iCurImage->Bpp + AlphaOff] / 255.0f; BackPer = 1.0f - FrontPer; for (c = 0; c < iCurImage->Bpp - 1; c++) { Dest->Data[DestIndex + c] = (ILubyte)(Converted[SrcIndex + c] * FrontPer + Dest->Data[DestIndex + c] * BackPer); } // Keep the original alpha. //Dest->Data[DestIndex + c + 1] = Dest->Data[DestIndex + c + 1]; } } } } else { for (z = StartZ; z < iCurImage->Depth && z + ZCoord < Dest->Depth; z++) { for (y = StartY; y < iCurImage->Height && y + YCoord < Dest->Height; y++) { for (x = StartX; x < iCurImage->Width && x + XCoord < Dest->Width; x++) { for (c = 0; c < iCurImage->Bpp; c++) { Dest->Data[(z + ZCoord) * Dest->SizeOfPlane + (y + YCoord) * Dest->Bps + (x + XCoord) * Dest->Bpp + c] = Converted[z * ConvSizePlane + y * ConvBps + x * Dest->Bpp + c]; } } } } } if (SrcTemp != iCurImage->Data) ifree(SrcTemp); ilBindImage(DestName); if (DestFlipped) ilFlipImage(); ifree(Converted); return IL_TRUE; }
//@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; }
ILAPI ILuint ILAPIENTRY il2CopyPixels(ILimage* image, ILuint XOff, ILuint YOff, ILuint ZOff, ILuint Width, ILuint Height, ILuint Depth, ILenum Format, ILenum Type, void *Data) { void *Converted = NULL; ILubyte *TempBuff = NULL; ILuint SrcSize, DestSize; if (image == NULL) { il2SetError(IL_ILLEGAL_OPERATION); return 0; } DestSize = Width * Height * Depth * ilGetBppFormat(Format) * ilGetBpcType(Type); if (DestSize == 0) { return DestSize; } if (Data == NULL || Format == IL_COLOUR_INDEX) { il2SetError(IL_INVALID_PARAM); return 0; } SrcSize = Width * Height * Depth * image->Bpp * image->Bpc; if (Format == image->Format && Type == image->Type) { TempBuff = (ILubyte*)Data; } else { TempBuff = (ILubyte*)ialloc(SrcSize); if (TempBuff == NULL) { return 0; } } if (YOff + Height <= 1) { if (!ilCopyPixels1D(image, XOff, Width, TempBuff)) { goto failed; } } else if (ZOff + Depth <= 1) { if (!ilCopyPixels2D(image, XOff, YOff, Width, Height, TempBuff)) { goto failed; } } else { if (!ilCopyPixels3D(image, XOff, YOff, ZOff, Width, Height, Depth, TempBuff)) { goto failed; } } if (Format == image->Format && Type == image->Type) { return DestSize; } Converted = ilConvertBuffer(SrcSize, image->Format, Format, image->Type, Type, &image->Pal, TempBuff); if (Converted == NULL) goto failed; memcpy(Data, Converted, DestSize); ifree(Converted); if (TempBuff != Data) ifree(TempBuff); return DestSize; failed: if (TempBuff != Data) ifree(TempBuff); ifree(Converted); return 0; }
//@NEXT DestX,DestY,DestZ must be set to ILuint ILboolean ILAPIENTRY ilBlit(ILuint Source, ILint DestX, ILint DestY, ILint DestZ, ILuint SrcX, ILuint SrcY, ILuint SrcZ, ILuint Width, ILuint Height, ILuint Depth) { ILuint x, y, z, ConvBps, ConvSizePlane; ILimage *Dest,*Src; ILubyte *Converted; ILuint DestName = ilGetCurName(); ILuint c; ILuint StartX, StartY, StartZ; ILboolean DestFlipped = IL_FALSE; ILubyte *SrcTemp; ILfloat Back; // Check if the desiination image really exists if( DestName == 0 || iCurImage == NULL ) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } Dest = iCurImage; // set the destination image to upper left origin if( Dest->Origin == IL_ORIGIN_LOWER_LEFT ) { // Dest DestFlipped = IL_TRUE; ilFlipImage(); } //DestOrigin = Dest->Origin; ilBindImage(Source); // Check if the source image really exists if( iCurImage == NULL ) { ilSetError(IL_INVALID_PARAM); return IL_FALSE; } Src = iCurImage; //@TODO test if coordinates are inside the images (hard limit for source) // set the source image to upper left origin if (Src->Origin == IL_ORIGIN_LOWER_LEFT) { SrcTemp = iGetFlipped(iCurImage); if (SrcTemp == NULL) { ilBindImage(DestName); if (DestFlipped) ilFlipImage(); return IL_FALSE; } } else { SrcTemp = iCurImage->Data; } // convert source image to match the destination image type and format Converted = (ILubyte*)ilConvertBuffer(Src->SizeOfData, Src->Format, Dest->Format, Src->Type, Dest->Type, SrcTemp); if (Converted == NULL) return IL_FALSE; ConvBps = Dest->Bpp * Src->Width; ConvSizePlane = ConvBps * Src->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 > Dest->Width) Width = Dest->Width - DestX; if (Height + DestY > Dest->Height) Height = Dest->Height - DestY; if (Depth + DestZ > Dest->Depth) Depth = Dest->Depth - DestZ; //@TODO: non funziona con rgba if (Src->Format == IL_RGBA || Src->Format == IL_BGRA || Src->Format == IL_LUMINANCE_ALPHA) { const ILuint bpp_without_alpha = Dest->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)*Dest->Bpp; const ILuint DestIndex = (z+DestZ)*Dest->SizeOfPlane + (y+DestY)*Dest->Bps + (x+DestX)*Dest->Bpp; const ILuint AlphaIdx = SrcIndex + bpp_without_alpha; ILfloat Front = 0; switch (Dest->Type) { case IL_BYTE: case IL_UNSIGNED_BYTE: Front = Converted[AlphaIdx]/((float)IL_MAX_UNSIGNED_BYTE); break; case IL_SHORT: case IL_UNSIGNED_SHORT: Front = ((ILshort*)Converted)[AlphaIdx]/((float)IL_MAX_UNSIGNED_SHORT); break; case IL_INT: case IL_UNSIGNED_INT: Front = ((ILint*)Converted)[AlphaIdx]/((float)IL_MAX_UNSIGNED_INT); break; case IL_FLOAT: Front = ((ILfloat*)Converted)[AlphaIdx]; break; case IL_DOUBLE: Front = (ILfloat)(((ILdouble*)Converted)[AlphaIdx]); break; } Back = 1.0f - Front; // In case of Alpha channel, the data is blended. Keeps the original alpha. if (ilIsEnabled(IL_BLIT_BLEND)) { for (c = 0; c < bpp_without_alpha; c++) { Dest->Data[DestIndex + c] = (ILubyte)(Converted[SrcIndex + c] * Front + Dest->Data[DestIndex + c] * Back); } } else { for (c = 0; c < Dest->Bpp; c++) { Dest->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 < Dest->Bpp; c++ ) { Dest->Data[(z+DestZ)*Dest->SizeOfPlane + (y+DestY)*Dest->Bps + (x+DestX)*Dest->Bpp + c] = Converted[(z+SrcZ)*ConvSizePlane + (y+SrcY)*ConvBps + (x+SrcX)*Dest->Bpp + c]; } } } } } if (SrcTemp != iCurImage->Data) ifree(SrcTemp); ilBindImage(DestName); if (DestFlipped) ilFlipImage(); ifree(Converted); return IL_TRUE; }