1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-09-08 14:17:06 +03:00

0032862: Visualization, Graphic3d_TextureMap - add 3D texture definition

Image_PixMap has been extended to support definition of 3D bitmap (as an array of 2D slices).

Graphic3d_TypeOfTexture enumeration values have been renamed to include full enum prefix.
Added Graphic3d_TypeOfTexture_3D redirecting to GL_TEXTURE_3D.
OpenGl_Texture::Init() has been extended to allow initialization of 3D texture.

Graphic3d_Texture2Dmanual merged into Graphic3d_Texture2D and marked as deprecated alias.
Graphic3d_TOT_2D_MIPMAP has been deprecated in favor of dedicated Graphic3d_TextureRoot::SetMipMaps().

Added Graphic3d_Texture3D class.
vtexture - added argument -3d for uploading 3D texture.
This commit is contained in:
kgv
2022-03-02 15:21:22 +03:00
committed by smoskvin
parent a9e5f65041
commit 633084b809
47 changed files with 1327 additions and 663 deletions

View File

@@ -73,7 +73,8 @@ namespace
};
}
IMPLEMENT_STANDARD_RTTIEXT(Image_PixMap,Standard_Transient)
IMPLEMENT_STANDARD_RTTIEXT(Image_PixMapData, NCollection_Buffer)
IMPLEMENT_STANDARD_RTTIEXT(Image_PixMap, Standard_Transient)
// =======================================================================
// function : DefaultAllocator
@@ -152,6 +153,31 @@ void Image_PixMap::SetFormat (Image_Format thePixelFormat)
myImgFormat = thePixelFormat;
}
// =======================================================================
// function : InitWrapper3D
// purpose :
// =======================================================================
bool Image_PixMap::InitWrapper3D (Image_Format thePixelFormat,
Standard_Byte* theDataPtr,
const NCollection_Vec3<Standard_Size>& theSizeXYZ,
const Standard_Size theSizeRowBytes)
{
Clear();
myImgFormat = thePixelFormat;
if (theSizeXYZ.x() == 0
|| theSizeXYZ.y() == 0
|| theSizeXYZ.z() == 0
|| theDataPtr == nullptr)
{
return false;
}
Handle(NCollection_BaseAllocator) anEmptyAlloc;
myData.Init (anEmptyAlloc, Image_PixMap::SizePixelBytes (thePixelFormat),
theSizeXYZ, theSizeRowBytes, theDataPtr);
return true;
}
// =======================================================================
// function : InitWrapper
// purpose :
@@ -161,18 +187,32 @@ bool Image_PixMap::InitWrapper (Image_Format thePixelFormat,
const Standard_Size theSizeX,
const Standard_Size theSizeY,
const Standard_Size theSizeRowBytes)
{
return InitWrapper3D (thePixelFormat, theDataPtr, NCollection_Vec3<Standard_Size> (theSizeX, theSizeY, 1), theSizeRowBytes);
}
// =======================================================================
// function : InitTrash3D
// purpose :
// =======================================================================
bool Image_PixMap::InitTrash3D (Image_Format thePixelFormat,
const NCollection_Vec3<Standard_Size>& theSizeXYZ,
const Standard_Size theSizeRowBytes)
{
Clear();
myImgFormat = thePixelFormat;
if ((theSizeX == 0) || (theSizeY == 0) || (theDataPtr == NULL))
if (theSizeXYZ.x() == 0
|| theSizeXYZ.y() == 0
|| theSizeXYZ.z() == 0)
{
return false;
}
Handle(NCollection_BaseAllocator) anEmptyAlloc;
myData.Init (anEmptyAlloc, Image_PixMap::SizePixelBytes (thePixelFormat),
theSizeX, theSizeY, theSizeRowBytes, theDataPtr);
return true;
// use argument only if it greater
const Standard_Size aSizeRowBytes = std::max (theSizeRowBytes, theSizeXYZ.x() * SizePixelBytes (thePixelFormat));
myData.Init (DefaultAllocator(), Image_PixMap::SizePixelBytes (thePixelFormat),
theSizeXYZ, aSizeRowBytes, NULL);
return !myData.IsEmpty();
}
// =======================================================================
@@ -184,33 +224,31 @@ bool Image_PixMap::InitTrash (Image_Format thePixelFormat,
const Standard_Size theSizeY,
const Standard_Size theSizeRowBytes)
{
Clear();
myImgFormat = thePixelFormat;
if ((theSizeX == 0) || (theSizeY == 0))
{
return false;
}
// use argument only if it greater
const Standard_Size aSizeRowBytes = std::max (theSizeRowBytes, theSizeX * SizePixelBytes (thePixelFormat));
myData.Init (DefaultAllocator(), Image_PixMap::SizePixelBytes (thePixelFormat),
theSizeX, theSizeY, aSizeRowBytes, NULL);
return !myData.IsEmpty();
return InitTrash3D (thePixelFormat, NCollection_Vec3<Standard_Size> (theSizeX, theSizeY, 1), theSizeRowBytes);
}
// =======================================================================
// function : InitZero
// function : InitZero3D
// purpose :
// =======================================================================
bool Image_PixMap::InitZero (Image_Format thePixelFormat,
const Standard_Size theSizeX,
const Standard_Size theSizeY,
const Standard_Size theSizeRowBytes,
const Standard_Byte theValue)
bool Image_PixMap::InitZero3D (Image_Format thePixelFormat,
const NCollection_Vec3<Standard_Size>& theSizeXYZ,
const Standard_Size theSizeRowBytes,
const Standard_Byte theValue)
{
if (!InitTrash (thePixelFormat, theSizeX, theSizeY, theSizeRowBytes))
if (theSizeXYZ.z() > 1)
{
return false;
if (!InitTrash3D (thePixelFormat, theSizeXYZ, theSizeRowBytes))
{
return false;
}
}
else
{
if (!InitTrash (thePixelFormat, theSizeXYZ.x(), theSizeXYZ.y(), theSizeRowBytes))
{
return false;
}
}
memset (myData.ChangeData(), (int )theValue, SizeBytes());
return true;
@@ -227,12 +265,24 @@ bool Image_PixMap::InitCopy (const Image_PixMap& theCopy)
// self-copying disallowed
return false;
}
if (InitTrash (theCopy.myImgFormat, theCopy.SizeX(), theCopy.SizeY(), theCopy.SizeRowBytes()))
if (theCopy.SizeZ() > 1)
{
memcpy (myData.ChangeData(), theCopy.myData.Data(), theCopy.SizeBytes());
return true;
if (!InitTrash3D (theCopy.myImgFormat, theCopy.SizeXYZ(), theCopy.SizeRowBytes()))
{
return false;
}
}
return false;
else
{
if (!InitTrash (theCopy.myImgFormat, theCopy.SizeX(), theCopy.SizeY(), theCopy.SizeRowBytes()))
{
return false;
}
}
memcpy (myData.ChangeData(), theCopy.myData.Data(), theCopy.SizeBytes());
return true;
}
// =======================================================================
@@ -243,80 +293,73 @@ void Image_PixMap::Clear()
{
Handle(NCollection_BaseAllocator) anEmptyAlloc;
myData.Init (anEmptyAlloc, Image_PixMap::SizePixelBytes (myImgFormat),
0, 0, 0, NULL);
NCollection_Vec3<Standard_Size> (0), 0, nullptr);
}
// =======================================================================
// function : PixelColor
// function : ColorFromRawPixel
// purpose :
// =======================================================================
Quantity_ColorRGBA Image_PixMap::PixelColor (const Standard_Integer theX,
const Standard_Integer theY,
const Standard_Boolean theToLinearize) const
Quantity_ColorRGBA Image_PixMap::ColorFromRawPixel (const Standard_Byte* theRawValue,
const Image_Format theFormat,
const Standard_Boolean theToLinearize)
{
if (IsEmpty()
|| theX < 0 || (Standard_Size )theX >= SizeX()
|| theY < 0 || (Standard_Size )theY >= SizeY())
{
return Quantity_ColorRGBA (0.0f, 0.0f, 0.0f, 0.0f); // transparent
}
switch (myImgFormat)
switch (theFormat)
{
case Image_Format_GrayF:
{
const Standard_ShortReal& aPixel = Value<Standard_ShortReal> (theY, theX);
const Standard_ShortReal& aPixel = *reinterpret_cast<const Standard_ShortReal*> (theRawValue);
return Quantity_ColorRGBA (NCollection_Vec4<float> (aPixel, aPixel, aPixel, 1.0f)); // opaque
}
case Image_Format_AlphaF:
{
const Standard_ShortReal& aPixel = Value<Standard_ShortReal> (theY, theX);
const Standard_ShortReal& aPixel = *reinterpret_cast<const Standard_ShortReal*> (theRawValue);
return Quantity_ColorRGBA (NCollection_Vec4<float> (1.0f, 1.0f, 1.0f, aPixel));
}
case Image_Format_RGF:
{
const Image_ColorRGF& aPixel = Value<Image_ColorRGF> (theY, theX);
const Image_ColorRGF& aPixel = *reinterpret_cast<const Image_ColorRGF*> (theRawValue);
return Quantity_ColorRGBA (NCollection_Vec4<float> (aPixel.r(), aPixel.g(), 0.0f, 1.0f));
}
case Image_Format_RGBAF:
{
const Image_ColorRGBAF& aPixel = Value<Image_ColorRGBAF> (theY, theX);
const Image_ColorRGBAF& aPixel = *reinterpret_cast<const Image_ColorRGBAF*> (theRawValue);
return Quantity_ColorRGBA (NCollection_Vec4<float> (aPixel.r(), aPixel.g(), aPixel.b(), aPixel.a()));
}
case Image_Format_BGRAF:
{
const Image_ColorBGRAF& aPixel = Value<Image_ColorBGRAF> (theY, theX);
const Image_ColorBGRAF& aPixel = *reinterpret_cast<const Image_ColorBGRAF*> (theRawValue);
return Quantity_ColorRGBA (NCollection_Vec4<float> (aPixel.r(), aPixel.g(), aPixel.b(), aPixel.a()));
}
case Image_Format_RGBF:
{
const Image_ColorRGBF& aPixel = Value<Image_ColorRGBF> (theY, theX);
const Image_ColorRGBF& aPixel = *reinterpret_cast<const Image_ColorRGBF*> (theRawValue);
return Quantity_ColorRGBA (NCollection_Vec4<float> (aPixel.r(), aPixel.g(), aPixel.b(), 1.0f)); // opaque
}
case Image_Format_BGRF:
{
const Image_ColorBGRF& aPixel = Value<Image_ColorBGRF> (theY, theX);
const Image_ColorBGRF& aPixel = *reinterpret_cast<const Image_ColorBGRF*> (theRawValue);
return Quantity_ColorRGBA (NCollection_Vec4<float> (aPixel.r(), aPixel.g(), aPixel.b(), 1.0f)); // opaque
}
case Image_Format_GrayF_half:
{
const uint16_t& aPixel = Value<uint16_t> (theY, theX);
const uint16_t& aPixel = *reinterpret_cast<const uint16_t*> (theRawValue);
return Quantity_ColorRGBA (NCollection_Vec4<float> (ConvertFromHalfFloat (aPixel), 0.0f, 0.0f, 1.0f));
}
case Image_Format_RGF_half:
{
const NCollection_Vec2<uint16_t>& aPixel = Value<NCollection_Vec2<uint16_t>> (theY, theX);
const NCollection_Vec2<uint16_t>& aPixel = *reinterpret_cast<const NCollection_Vec2<uint16_t>*> (theRawValue);
return Quantity_ColorRGBA (NCollection_Vec4<float> (ConvertFromHalfFloat (aPixel.x()), ConvertFromHalfFloat (aPixel.y()), 0.0f, 1.0f));
}
case Image_Format_RGBAF_half:
{
const NCollection_Vec4<uint16_t>& aPixel = Value<NCollection_Vec4<uint16_t>> (theY, theX);
const NCollection_Vec4<uint16_t>& aPixel = *reinterpret_cast<const NCollection_Vec4<uint16_t>*> (theRawValue);
return Quantity_ColorRGBA (NCollection_Vec4<float> (ConvertFromHalfFloat (aPixel.r()), ConvertFromHalfFloat (aPixel.g()),
ConvertFromHalfFloat (aPixel.b()), ConvertFromHalfFloat (aPixel.a())));
}
case Image_Format_RGBA:
{
const Image_ColorRGBA& aPixel = Value<Image_ColorRGBA> (theY, theX);
const Image_ColorRGBA& aPixel = *reinterpret_cast<const Image_ColorRGBA*> (theRawValue);
return theToLinearize
? Quantity_ColorRGBA (Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.r()) / 255.0f),
Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.g()) / 255.0f),
@@ -326,7 +369,7 @@ Quantity_ColorRGBA Image_PixMap::PixelColor (const Standard_Integer theX,
}
case Image_Format_BGRA:
{
const Image_ColorBGRA& aPixel = Value<Image_ColorBGRA> (theY, theX);
const Image_ColorBGRA& aPixel = *reinterpret_cast<const Image_ColorBGRA*> (theRawValue);
return theToLinearize
? Quantity_ColorRGBA (Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.r()) / 255.0f),
Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.g()) / 255.0f),
@@ -336,7 +379,7 @@ Quantity_ColorRGBA Image_PixMap::PixelColor (const Standard_Integer theX,
}
case Image_Format_RGB32:
{
const Image_ColorRGB32& aPixel = Value<Image_ColorRGB32> (theY, theX);
const Image_ColorRGB32& aPixel = *reinterpret_cast<const Image_ColorRGB32*> (theRawValue);
return theToLinearize
? Quantity_ColorRGBA (Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.r()) / 255.0f),
Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.g()) / 255.0f),
@@ -345,7 +388,7 @@ Quantity_ColorRGBA Image_PixMap::PixelColor (const Standard_Integer theX,
}
case Image_Format_BGR32:
{
const Image_ColorBGR32& aPixel = Value<Image_ColorBGR32> (theY, theX);
const Image_ColorBGR32& aPixel = *reinterpret_cast<const Image_ColorBGR32*> (theRawValue);
return theToLinearize
? Quantity_ColorRGBA (Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.r()) / 255.0f),
Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.g()) / 255.0f),
@@ -354,7 +397,7 @@ Quantity_ColorRGBA Image_PixMap::PixelColor (const Standard_Integer theX,
}
case Image_Format_RGB:
{
const Image_ColorRGB& aPixel = Value<Image_ColorRGB> (theY, theX);
const Image_ColorRGB& aPixel = *reinterpret_cast<const Image_ColorRGB*> (theRawValue);
return theToLinearize
? Quantity_ColorRGBA (Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.r()) / 255.0f),
Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.g()) / 255.0f),
@@ -363,7 +406,7 @@ Quantity_ColorRGBA Image_PixMap::PixelColor (const Standard_Integer theX,
}
case Image_Format_BGR:
{
const Image_ColorBGR& aPixel = Value<Image_ColorBGR> (theY, theX);
const Image_ColorBGR& aPixel = *reinterpret_cast<const Image_ColorBGR*> (theRawValue);
return theToLinearize
? Quantity_ColorRGBA (Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.r()) / 255.0f),
Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.g()) / 255.0f),
@@ -372,18 +415,18 @@ Quantity_ColorRGBA Image_PixMap::PixelColor (const Standard_Integer theX,
}
case Image_Format_Gray:
{
const Standard_Byte& aPixel = Value<Standard_Byte> (theY, theX);
const Standard_Byte& aPixel = *reinterpret_cast<const Standard_Byte*> (theRawValue);
const float anIntensity = float(aPixel) / 255.0f;
return Quantity_ColorRGBA (anIntensity, anIntensity, anIntensity, 1.0f); // opaque
}
case Image_Format_Alpha:
{
const Standard_Byte& aPixel = Value<Standard_Byte> (theY, theX);
const Standard_Byte& aPixel = *reinterpret_cast<const Standard_Byte*> (theRawValue);
return Quantity_ColorRGBA (1.0f, 1.0f, 1.0f, float(aPixel) / 255.0f);
}
case Image_Format_Gray16:
{
const uint16_t& aPixel = Value<uint16_t> (theY, theX);
const uint16_t& aPixel = *reinterpret_cast<const uint16_t*> (theRawValue);
const float anIntensity = float(aPixel) / 65535.0f;
return Quantity_ColorRGBA (anIntensity, anIntensity, anIntensity, 1.0f); // opaque
}
@@ -398,44 +441,37 @@ Quantity_ColorRGBA Image_PixMap::PixelColor (const Standard_Integer theX,
}
// =======================================================================
// function : SetPixelColor
// function : ColorToRawPixel
// purpose :
// =======================================================================
void Image_PixMap::SetPixelColor (const Standard_Integer theX,
const Standard_Integer theY,
const Quantity_ColorRGBA& theColor,
const Standard_Boolean theToDeLinearize)
void Image_PixMap::ColorToRawPixel (Standard_Byte* theRawValue,
const Image_Format theFormat,
const Quantity_ColorRGBA& theColor,
const Standard_Boolean theToDeLinearize)
{
if (IsEmpty()
|| theX < 0 || Standard_Size(theX) >= SizeX()
|| theY < 0 || Standard_Size(theY) >= SizeY())
{
return;
}
const NCollection_Vec4<float>& aColor = theColor;
switch (myImgFormat)
switch (theFormat)
{
case Image_Format_GrayF:
{
ChangeValue<Standard_ShortReal> (theY, theX) = aColor.r();
*reinterpret_cast<Standard_ShortReal*> (theRawValue) = aColor.r();
return;
}
case Image_Format_AlphaF:
{
ChangeValue<Standard_ShortReal> (theY, theX) = aColor.a();
*reinterpret_cast<Standard_ShortReal*> (theRawValue) = aColor.a();
return;
}
case Image_Format_RGF:
{
Image_ColorRGF& aPixel = ChangeValue<Image_ColorRGF> (theY, theX);
Image_ColorRGF& aPixel = *reinterpret_cast<Image_ColorRGF*> (theRawValue);
aPixel.r() = aColor.r();
aPixel.g() = aColor.g();
return;
}
case Image_Format_RGBAF:
{
Image_ColorRGBAF& aPixel = ChangeValue<Image_ColorRGBAF> (theY, theX);
Image_ColorRGBAF& aPixel = *reinterpret_cast<Image_ColorRGBAF*> (theRawValue);
aPixel.r() = aColor.r();
aPixel.g() = aColor.g();
aPixel.b() = aColor.b();
@@ -444,7 +480,7 @@ void Image_PixMap::SetPixelColor (const Standard_Integer theX,
}
case Image_Format_BGRAF:
{
Image_ColorBGRAF& aPixel = ChangeValue<Image_ColorBGRAF> (theY, theX);
Image_ColorBGRAF& aPixel = *reinterpret_cast<Image_ColorBGRAF*> (theRawValue);
aPixel.r() = aColor.r();
aPixel.g() = aColor.g();
aPixel.b() = aColor.b();
@@ -453,7 +489,7 @@ void Image_PixMap::SetPixelColor (const Standard_Integer theX,
}
case Image_Format_RGBF:
{
Image_ColorRGBF& aPixel = ChangeValue<Image_ColorRGBF> (theY, theX);
Image_ColorRGBF& aPixel = *reinterpret_cast<Image_ColorRGBF*> (theRawValue);
aPixel.r() = aColor.r();
aPixel.g() = aColor.g();
aPixel.b() = aColor.b();
@@ -461,7 +497,7 @@ void Image_PixMap::SetPixelColor (const Standard_Integer theX,
}
case Image_Format_BGRF:
{
Image_ColorBGRF& aPixel = ChangeValue<Image_ColorBGRF> (theY, theX);
Image_ColorBGRF& aPixel = *reinterpret_cast<Image_ColorBGRF*> (theRawValue);
aPixel.r() = aColor.r();
aPixel.g() = aColor.g();
aPixel.b() = aColor.b();
@@ -469,20 +505,20 @@ void Image_PixMap::SetPixelColor (const Standard_Integer theX,
}
case Image_Format_GrayF_half:
{
uint16_t& aPixel = ChangeValue<uint16_t> (theY, theX);
uint16_t& aPixel = *reinterpret_cast<uint16_t*> (theRawValue);
aPixel = ConvertToHalfFloat (aColor.r());
return;
}
case Image_Format_RGF_half:
{
NCollection_Vec2<uint16_t>& aPixel = ChangeValue<NCollection_Vec2<uint16_t>> (theY, theX);
NCollection_Vec2<uint16_t>& aPixel = *reinterpret_cast<NCollection_Vec2<uint16_t>*> (theRawValue);
aPixel.x() = ConvertToHalfFloat (aColor.r());
aPixel.y() = ConvertToHalfFloat (aColor.g());
return;
}
case Image_Format_RGBAF_half:
{
NCollection_Vec4<uint16_t>& aPixel = ChangeValue<NCollection_Vec4<uint16_t>> (theY, theX);
NCollection_Vec4<uint16_t>& aPixel = *reinterpret_cast<NCollection_Vec4<uint16_t>*> (theRawValue);
aPixel.r() = ConvertToHalfFloat (aColor.r());
aPixel.g() = ConvertToHalfFloat (aColor.g());
aPixel.b() = ConvertToHalfFloat (aColor.b());
@@ -491,7 +527,7 @@ void Image_PixMap::SetPixelColor (const Standard_Integer theX,
}
case Image_Format_RGBA:
{
Image_ColorRGBA& aPixel = ChangeValue<Image_ColorRGBA> (theY, theX);
Image_ColorRGBA& aPixel = *reinterpret_cast<Image_ColorRGBA*> (theRawValue);
if (theToDeLinearize)
{
aPixel.r() = Standard_Byte(Quantity_Color::Convert_LinearRGB_To_sRGB (aColor.r()) * 255.0f);
@@ -509,7 +545,7 @@ void Image_PixMap::SetPixelColor (const Standard_Integer theX,
}
case Image_Format_BGRA:
{
Image_ColorBGRA& aPixel = ChangeValue<Image_ColorBGRA> (theY, theX);
Image_ColorBGRA& aPixel = *reinterpret_cast<Image_ColorBGRA*> (theRawValue);
if (theToDeLinearize)
{
aPixel.r() = Standard_Byte(Quantity_Color::Convert_LinearRGB_To_sRGB (aColor.r()) * 255.0f);
@@ -527,7 +563,7 @@ void Image_PixMap::SetPixelColor (const Standard_Integer theX,
}
case Image_Format_RGB32:
{
Image_ColorRGB32& aPixel = ChangeValue<Image_ColorRGB32> (theY, theX);
Image_ColorRGB32& aPixel = *reinterpret_cast<Image_ColorRGB32*> (theRawValue);
if (theToDeLinearize)
{
aPixel.r() = Standard_Byte(Quantity_Color::Convert_LinearRGB_To_sRGB (aColor.r()) * 255.0f);
@@ -545,7 +581,7 @@ void Image_PixMap::SetPixelColor (const Standard_Integer theX,
}
case Image_Format_BGR32:
{
Image_ColorBGR32& aPixel = ChangeValue<Image_ColorBGR32> (theY, theX);
Image_ColorBGR32& aPixel = *reinterpret_cast<Image_ColorBGR32*> (theRawValue);
if (theToDeLinearize)
{
aPixel.r() = Standard_Byte(Quantity_Color::Convert_LinearRGB_To_sRGB (aColor.r()) * 255.0f);
@@ -563,7 +599,7 @@ void Image_PixMap::SetPixelColor (const Standard_Integer theX,
}
case Image_Format_RGB:
{
Image_ColorRGB& aPixel = ChangeValue<Image_ColorRGB> (theY, theX);
Image_ColorRGB& aPixel = *reinterpret_cast<Image_ColorRGB*> (theRawValue);
if (theToDeLinearize)
{
aPixel.r() = Standard_Byte(Quantity_Color::Convert_LinearRGB_To_sRGB (aColor.r()) * 255.0f);
@@ -580,7 +616,7 @@ void Image_PixMap::SetPixelColor (const Standard_Integer theX,
}
case Image_Format_BGR:
{
Image_ColorBGR& aPixel = ChangeValue<Image_ColorBGR> (theY, theX);
Image_ColorBGR& aPixel = *reinterpret_cast<Image_ColorBGR*> (theRawValue);
if (theToDeLinearize)
{
aPixel.r() = Standard_Byte(Quantity_Color::Convert_LinearRGB_To_sRGB (aColor.r()) * 255.0f);
@@ -597,17 +633,17 @@ void Image_PixMap::SetPixelColor (const Standard_Integer theX,
}
case Image_Format_Gray:
{
ChangeValue<Standard_Byte> (theY, theX) = Standard_Byte(aColor.r() * 255.0f);
*reinterpret_cast<Standard_Byte*>(theRawValue) = Standard_Byte(aColor.r() * 255.0f);
return;
}
case Image_Format_Alpha:
{
ChangeValue<Standard_Byte> (theY, theX) = Standard_Byte(aColor.a() * 255.0f);
*reinterpret_cast<Standard_Byte*>(theRawValue) = Standard_Byte(aColor.a() * 255.0f);
return;
}
case Image_Format_Gray16:
{
ChangeValue<uint16_t> (theY, theX) = uint16_t(aColor.r() * 65535.0f);
*reinterpret_cast<uint16_t*>(theRawValue) = uint16_t(aColor.r() * 65535.0f);
return;
}
case Image_Format_UNKNOWN:
@@ -632,18 +668,21 @@ bool Image_PixMap::SwapRgbaBgra (Image_PixMap& theImage)
{
const bool toResetAlpha = theImage.Format() == Image_Format_BGR32
|| theImage.Format() == Image_Format_RGB32;
for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
for (Standard_Size aSlice = 0; aSlice < theImage.SizeZ(); ++aSlice)
{
for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol)
for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
{
Image_ColorRGBA& aPixel = theImage.ChangeValue<Image_ColorRGBA> (aRow, aCol);
Image_ColorBGRA aPixelCopy = theImage.Value <Image_ColorBGRA> (aRow, aCol);
aPixel.r() = aPixelCopy.r();
aPixel.g() = aPixelCopy.g();
aPixel.b() = aPixelCopy.b();
if (toResetAlpha)
for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol)
{
aPixel.a() = 255;
Image_ColorRGBA& aPixel = theImage.ChangeValueXYZ<Image_ColorRGBA> (aCol, aRow, aSlice);
Image_ColorBGRA aPixelCopy = theImage.ValueXYZ <Image_ColorBGRA> (aCol, aRow, aSlice);
aPixel.r() = aPixelCopy.r();
aPixel.g() = aPixelCopy.g();
aPixel.b() = aPixelCopy.b();
if (toResetAlpha)
{
aPixel.a() = 255;
}
}
}
}
@@ -652,15 +691,18 @@ bool Image_PixMap::SwapRgbaBgra (Image_PixMap& theImage)
case Image_Format_BGR:
case Image_Format_RGB:
{
for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
for (Standard_Size aSlice = 0; aSlice < theImage.SizeZ(); ++aSlice)
{
for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol)
for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
{
Image_ColorRGB& aPixel = theImage.ChangeValue<Image_ColorRGB> (aRow, aCol);
Image_ColorBGR aPixelCopy = theImage.Value <Image_ColorBGR> (aRow, aCol);
aPixel.r() = aPixelCopy.r();
aPixel.g() = aPixelCopy.g();
aPixel.b() = aPixelCopy.b();
for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol)
{
Image_ColorRGB& aPixel = theImage.ChangeValueXYZ<Image_ColorRGB> (aCol, aRow, aSlice);
Image_ColorBGR aPixelCopy = theImage.ValueXYZ <Image_ColorBGR> (aCol, aRow, aSlice);
aPixel.r() = aPixelCopy.r();
aPixel.g() = aPixelCopy.g();
aPixel.b() = aPixelCopy.b();
}
}
}
return true;
@@ -670,15 +712,18 @@ bool Image_PixMap::SwapRgbaBgra (Image_PixMap& theImage)
case Image_Format_BGRAF:
case Image_Format_RGBAF:
{
for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
for (Standard_Size aSlice = 0; aSlice < theImage.SizeZ(); ++aSlice)
{
for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol)
for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
{
Image_ColorRGBF& aPixel = theImage.ChangeValue<Image_ColorRGBF> (aRow, aCol);
Image_ColorBGRF aPixelCopy = theImage.Value <Image_ColorBGRF> (aRow, aCol);
aPixel.r() = aPixelCopy.r();
aPixel.g() = aPixelCopy.g();
aPixel.b() = aPixelCopy.b();
for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol)
{
Image_ColorRGBF& aPixel = theImage.ChangeValueXYZ<Image_ColorRGBF> (aCol, aRow, aSlice);
Image_ColorBGRF aPixelCopy = theImage.ValueXYZ <Image_ColorBGRF> (aCol, aRow, aSlice);
aPixel.r() = aPixelCopy.r();
aPixel.g() = aPixelCopy.g();
aPixel.b() = aPixelCopy.b();
}
}
}
return true;
@@ -698,14 +743,17 @@ void Image_PixMap::ToBlackWhite (Image_PixMap& theImage)
case Image_Format_Gray:
case Image_Format_Alpha:
{
for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
for (Standard_Size aSlice = 0; aSlice < theImage.SizeZ(); ++aSlice)
{
for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol)
for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
{
unsigned char& aPixel = theImage.ChangeValue<unsigned char> (aRow, aCol);
if (aPixel != 0)
for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol)
{
aPixel = 255;
uint8_t& aPixel = theImage.ChangeValueXYZ<uint8_t> (aCol, aRow, aSlice);
if (aPixel != 0)
{
aPixel = 255;
}
}
}
}
@@ -713,14 +761,17 @@ void Image_PixMap::ToBlackWhite (Image_PixMap& theImage)
}
case Image_Format_Gray16:
{
for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
for (Standard_Size aSlice = 0; aSlice < theImage.SizeZ(); ++aSlice)
{
for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol)
for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
{
uint16_t& aPixel = theImage.ChangeValue<uint16_t> (aRow, aCol);
if (aPixel != 0)
for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol)
{
aPixel = 65535;
uint16_t& aPixel = theImage.ChangeValueXYZ<uint16_t> (aCol, aRow, aSlice);
if (aPixel != 0)
{
aPixel = 65535;
}
}
}
}
@@ -733,17 +784,20 @@ void Image_PixMap::ToBlackWhite (Image_PixMap& theImage)
case Image_Format_RGBA:
case Image_Format_BGRA:
{
const NCollection_Vec3<unsigned char> aWhite24 (255, 255, 255);
for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
const NCollection_Vec3<uint8_t> aWhite24 (255, 255, 255);
for (Standard_Size aSlice = 0; aSlice < theImage.SizeZ(); ++aSlice)
{
for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol)
for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
{
NCollection_Vec3<unsigned char>& aPixel = theImage.ChangeValue< NCollection_Vec3<unsigned char> > (aRow, aCol);
if (aPixel[0] != 0
|| aPixel[1] != 0
|| aPixel[2] != 0)
for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol)
{
aPixel = aWhite24;
NCollection_Vec3<uint8_t>& aPixel = theImage.ChangeValueXYZ< NCollection_Vec3<uint8_t> > (aCol, aRow, aSlice);
if (aPixel[0] != 0
|| aPixel[1] != 0
|| aPixel[2] != 0)
{
aPixel = aWhite24;
}
}
}
}
@@ -752,17 +806,21 @@ void Image_PixMap::ToBlackWhite (Image_PixMap& theImage)
default:
{
const Quantity_ColorRGBA aWhiteRgba (1.0f, 1.0f, 1.0f, 1.0f);
for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
for (Standard_Size aSlice = 0; aSlice < theImage.SizeZ(); ++aSlice)
{
for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol)
for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
{
const Quantity_ColorRGBA aPixelRgba = theImage.PixelColor (Standard_Integer(aCol), Standard_Integer(aRow));
const NCollection_Vec4<float>& aPixel = aPixelRgba;
if (aPixel[0] != 0.0f
|| aPixel[1] != 0.0f
|| aPixel[2] != 0.0f)
for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol)
{
theImage.SetPixelColor (int(aCol), int(aRow), aWhiteRgba);
Standard_Byte* aRawPixel = theImage.ChangeRawValueXYZ (aCol, aRow, aSlice);
const Quantity_ColorRGBA aPixelRgba = ColorFromRawPixel (aRawPixel, theImage.Format());
const NCollection_Vec4<float>& aPixel = aPixelRgba;
if (aPixel[0] != 0.0f
|| aPixel[1] != 0.0f
|| aPixel[2] != 0.0f)
{
ColorToRawPixel (aRawPixel, theImage.Format(), aWhiteRgba);
}
}
}
}
@@ -772,7 +830,7 @@ void Image_PixMap::ToBlackWhite (Image_PixMap& theImage)
}
// =======================================================================
// function : InitCopy
// function : FlipY
// purpose :
// =======================================================================
bool Image_PixMap::FlipY (Image_PixMap& theImage)
@@ -793,13 +851,16 @@ bool Image_PixMap::FlipY (Image_PixMap& theImage)
// for odd height middle row should be left as is
Standard_Size aNbRowsHalf = theImage.SizeY() / 2;
for (Standard_Size aRowT = 0, aRowB = theImage.SizeY() - 1; aRowT < aNbRowsHalf; ++aRowT, --aRowB)
for (Standard_Size aSlice = 0; aSlice < theImage.SizeZ(); ++aSlice)
{
Standard_Byte* aTop = theImage.ChangeRow (aRowT);
Standard_Byte* aBot = theImage.ChangeRow (aRowB);
memcpy (aTmp.ChangeData(), aTop, aRowSize);
memcpy (aTop, aBot, aRowSize);
memcpy (aBot, aTmp.Data(), aRowSize);
for (Standard_Size aRowT = 0, aRowB = theImage.SizeY() - 1; aRowT < aNbRowsHalf; ++aRowT, --aRowB)
{
Standard_Byte* aTop = theImage.ChangeSliceRow (aSlice, aRowT);
Standard_Byte* aBot = theImage.ChangeSliceRow (aSlice, aRowB);
memcpy (aTmp.ChangeData(), aTop, aRowSize);
memcpy (aTop, aBot, aRowSize);
memcpy (aBot, aTmp.Data(), aRowSize);
}
}
return true;
}

View File

@@ -35,6 +35,9 @@ public:
return !aUnion.myChar[0];
}
//! Return bytes reserved for one pixel (may include extra bytes for alignment).
Standard_EXPORT static Standard_Size SizePixelBytes (const Image_Format thePixelFormat);
//! Auxiliary method for swapping bytes between RGB and BGR formats.
//! This method modifies the image data but does not change pixel format!
//! Method will fail if pixel format is not one of the following:
@@ -60,6 +63,25 @@ public:
//! Return string representation of compressed pixel format.
Standard_EXPORT static Standard_CString ImageFormatToString (Image_CompressedFormat theFormat);
//! Convert raw pixel value into Quantity_ColorRGBA. This function is relatively slow.
//! @param[in] theRawValue pointer to pixel definition
//! @param[in] theFormat pixel format
//! @param[in] theToLinearize when TRUE, the color stored in non-linear color space (e.g. Image_Format_RGB) will be linearized
//! @return the pixel color
Standard_EXPORT static Quantity_ColorRGBA ColorFromRawPixel (const Standard_Byte* theRawValue,
const Image_Format theFormat,
const Standard_Boolean theToLinearize = false);
//! Set raw pixel value from Quantity_ColorRGBA. This function is relatively slow.
//! @param[out] theRawValue pointer to pixel definition to modify
//! @param[in] theFormat pixel format
//! @param[in] theColor color value to convert from
//! @param[in] theToDeLinearize when TRUE, the gamma correction will be applied for storing in non-linear color space (e.g. Image_Format_RGB)
Standard_EXPORT static void ColorToRawPixel (Standard_Byte* theRawValue,
const Image_Format theFormat,
const Quantity_ColorRGBA& theColor,
const Standard_Boolean theToDeLinearize = false);
public: // high-level API
//! Return pixel format.
@@ -71,18 +93,30 @@ public: // high-level API
//! (e.g. ImgGray and ImgAlpha).
Standard_EXPORT void SetFormat (const Image_Format thePixelFormat);
//! Return image width in pixels
//! Return image width in pixels.
Standard_Size Width() const { return myData.SizeX; }
//! Return image height in pixels
//! Return image height in pixels.
Standard_Size Height() const { return myData.SizeY; }
//! Return image width in pixels
//! Return image depth in pixels.
Standard_Size Depth() const { return myData.SizeZ; }
//! Return image width in pixels.
Standard_Size SizeX() const { return myData.SizeX; }
//! Return image height in pixels
//! Return image height in pixels.
Standard_Size SizeY() const { return myData.SizeY; }
//! Return image depth in pixels.
Standard_Size SizeZ() const { return myData.SizeZ; }
//! Return image width x height x depth in pixels.
NCollection_Vec3<Standard_Size> SizeXYZ() const
{
return NCollection_Vec3<Standard_Size> (myData.SizeX, myData.SizeY, myData.SizeZ);
}
//! Return width / height.
Standard_Real Ratio() const
{
@@ -100,38 +134,60 @@ public: // high-level API
//! Returns the pixel color. This function is relatively slow.
//! Beware that this method takes coordinates in opposite order in contrast to ::Value() and ::ChangeValue().
//! @param theX [in] column index from left
//! @param theY [in] row index from top
//! @param theToLinearize [in] when TRUE, the color stored in non-linear color space (e.g. Image_Format_RGB) will be linearized
//! @param[in] theX column index from left, starting from 0
//! @param[in] theY row index from top, starting from 0
//! @param[in] theToLinearize when TRUE, the color stored in non-linear color space (e.g. Image_Format_RGB) will be linearized
//! @return the pixel color
Standard_EXPORT Quantity_ColorRGBA PixelColor (const Standard_Integer theX,
const Standard_Integer theY,
const Standard_Boolean theToLinearize = Standard_False) const;
Quantity_ColorRGBA PixelColor (Standard_Integer theX,
Standard_Integer theY,
Standard_Boolean theToLinearize = false) const
{
if (IsEmpty()
|| theX < 0 || (Standard_Size )theX >= SizeX()
|| theY < 0 || (Standard_Size )theY >= SizeY())
{
return Quantity_ColorRGBA (0.0f, 0.0f, 0.0f, 0.0f); // transparent
}
const Standard_Byte* aRawPixel = RawValueXY (theX, theY);
return ColorFromRawPixel (aRawPixel, myImgFormat, theToLinearize);
}
//! Sets the pixel color. This function is relatively slow.
//! Beware that this method takes coordinates in opposite order in contrast to ::Value() and ::ChangeValue().
//! @param theX [in] column index from left
//! @param theY [in] row index from top
//! @param theColor [in] color to store
//! @param theToDeLinearize [in] when TRUE, the gamma correction will be applied for storing in non-linear color space (e.g. Image_Format_RGB)
//! @param[in] theX column index from left
//! @param[in] theY row index from top
//! @param[in] theColor color to store
//! @param[in] theToDeLinearize when TRUE, the gamma correction will be applied for storing in non-linear color space (e.g. Image_Format_RGB)
void SetPixelColor (const Standard_Integer theX,
const Standard_Integer theY,
const Quantity_Color& theColor,
const Standard_Boolean theToDeLinearize = Standard_False)
const Standard_Boolean theToDeLinearize = false)
{
SetPixelColor (theX, theY, Quantity_ColorRGBA (theColor, 1.0f), theToDeLinearize);
}
//! Sets the pixel color. This function is relatively slow.
//! Beware that this method takes coordinates in opposite order in contrast to ::Value() and ::ChangeValue().
//! @param theX [in] column index from left
//! @param theY [in] row index from top
//! @param theColor [in] color to store
//! @param theToDeLinearize [in] when TRUE, the gamma correction will be applied for storing in non-linear color space (e.g. Image_Format_RGB)
Standard_EXPORT void SetPixelColor (const Standard_Integer theX,
const Standard_Integer theY,
const Quantity_ColorRGBA& theColor,
const Standard_Boolean theToDeLinearize = Standard_False);
//! @param[in] theX column index from left
//! @param[in] theY row index from top
//! @param[in] theColor color to store
//! @param[in] theToDeLinearize when TRUE, the gamma correction will be applied for storing in non-linear color space (e.g. Image_Format_RGB)
void SetPixelColor (const Standard_Integer theX,
const Standard_Integer theY,
const Quantity_ColorRGBA& theColor,
const Standard_Boolean theToDeLinearize = false)
{
if (IsEmpty()
|| theX < 0 || Standard_Size(theX) >= SizeX()
|| theY < 0 || Standard_Size(theY) >= SizeY())
{
return;
}
Standard_Byte* aRawPixel = ChangeRawValueXY (theX, theY);
ColorToRawPixel (aRawPixel, myImgFormat, theColor, theToDeLinearize);
}
//! Initialize image plane as wrapper over alien data.
//! Data will not be copied! Notice that caller should ensure
@@ -156,15 +212,42 @@ public: // high-level API
//! Initialize image plane with required dimensions.
//! Buffer will be zeroed (black color for most formats).
Standard_EXPORT bool InitZero (Image_Format thePixelFormat,
const Standard_Size theSizeX,
const Standard_Size theSizeY,
const Standard_Size theSizeRowBytes = 0,
const Standard_Byte theValue = 0);
bool InitZero (Image_Format thePixelFormat,
const Standard_Size theSizeX,
const Standard_Size theSizeY,
const Standard_Size theSizeRowBytes = 0,
const Standard_Byte theValue = 0)
{
return InitZero3D (thePixelFormat, NCollection_Vec3<Standard_Size> (theSizeX, theSizeY, 1), theSizeRowBytes, theValue);
}
//! Method correctly deallocate internal buffer.
Standard_EXPORT virtual void Clear();
public:
//! Initialize 2D/3D image as wrapper over alien data.
//! Data will not be copied! Notice that caller should ensure
//! that data pointer will not be released during this wrapper lifetime.
//! You may call InitCopy() to perform data copying.
Standard_EXPORT virtual bool InitWrapper3D (Image_Format thePixelFormat,
Standard_Byte* theDataPtr,
const NCollection_Vec3<Standard_Size>& theSizeXYZ,
const Standard_Size theSizeRowBytes = 0);
//! Initialize 2D/3D image with required dimensions.
//! Memory will be left uninitialized (performance trick).
Standard_EXPORT virtual bool InitTrash3D (Image_Format thePixelFormat,
const NCollection_Vec3<Standard_Size>& theSizeXYZ,
const Standard_Size theSizeRowBytes = 0);
//! Initialize 2D/3D image with required dimensions.
//! Buffer will be zeroed (black color for most formats).
Standard_EXPORT bool InitZero3D (Image_Format thePixelFormat,
const NCollection_Vec3<Standard_Size>& theSizeXYZ,
const Standard_Size theSizeRowBytes = 0,
const Standard_Byte theValue = 0);
public: //! @name low-level API for batch-processing (pixels reading / comparison / modification)
//! Returns TRUE if image data is stored from Top to the Down.
@@ -176,105 +259,106 @@ public: //! @name low-level API for batch-processing (pixels reading / compariso
//! convert input row-index to apply this flag!
//! You should use this flag only if interconnect with alien APIs and buffers.
//! @return true if image data is top-down
inline bool IsTopDown() const
{
return myData.TopToDown == 1;
}
bool IsTopDown() const { return myData.TopToDown == 1; }
//! Setup scanlines order in memory - top-down or bottom-up.
//! Drawers should explicitly specify this value if current state IsTopDown() was ignored!
//! @param theIsTopDown top-down flag
inline void SetTopDown (const bool theIsTopDown)
{
myData.SetTopDown (theIsTopDown);
}
void SetTopDown (const bool theIsTopDown) { myData.SetTopDown (theIsTopDown); }
//! Returns +1 if scanlines ordered in Top->Down order in memory and -1 otherwise.
//! @return scanline increment for Top->Down iteration
inline Standard_Size TopDownInc() const
Standard_Size TopDownInc() const { return myData.TopToDown; }
//! Return data pointer for low-level operations (copying entire buffer, parsing with extra tools etc.).
const Standard_Byte* Data() const { return myData.Data(); }
//! Return data pointer for low-level operations (copying entire buffer, parsing with extra tools etc.).
Standard_Byte* ChangeData() { return myData.ChangeData(); }
//! Return data pointer to requested row (first column).
//! Indexation starts from 0.
const Standard_Byte* Row (Standard_Size theRow) const { return myData.Row (theRow); }
//! Return data pointer to requested row (first column).
//! Indexation starts from 0.
Standard_Byte* ChangeRow (Standard_Size theRow) { return myData.ChangeRow (theRow); }
//! Return data pointer to requested 2D slice.
//! Indexation starts from 0.
const Standard_Byte* Slice (Standard_Size theSlice) const { return myData.Slice (theSlice); }
//! Return data pointer to requested 2D slice.
//! Indexation starts from 0.
Standard_Byte* ChangeSlice (Standard_Size theSlice) { return myData.ChangeSlice (theSlice); }
//! Return data pointer to requested row (first column).
//! Indexation starts from 0.
const Standard_Byte* SliceRow (Standard_Size theSlice,
Standard_Size theRow) const
{
return myData.TopToDown;
return myData.SliceRow (theSlice, theRow);
}
//! @return data pointer for low-level operations (copying entire buffer, parsing with extra tools etc.).
inline const Standard_Byte* Data() const
//! Return data pointer to requested row (first column).
//! Indexation starts from 0.
Standard_Byte* ChangeSliceRow (Standard_Size theSlice,
Standard_Size theRow)
{
return myData.Data();
return myData.ChangeSliceRow (theSlice, theRow);
}
//! @return data pointer for low-level operations (copying entire buffer, parsing with extra tools etc.).
inline Standard_Byte* ChangeData()
{
return myData.ChangeData();
}
//! Return bytes reserved for one pixel (may include extra bytes for alignment).
Standard_Size SizePixelBytes() const { return myData.SizeBPP; }
//! @return data pointer to requested row (first column).
inline const Standard_Byte* Row (const Standard_Size theRow) const
{
return myData.Row (theRow);
}
//! @return data pointer to requested row (first column).
inline Standard_Byte* ChangeRow (const Standard_Size theRow)
{
return myData.ChangeRow (theRow);
}
//! @return bytes reserved for one pixel (may include extra bytes for alignment).
inline Standard_Size SizePixelBytes() const
{
return myData.SizeBPP;
}
//! @return bytes reserved for one pixel (may include extra bytes for alignment).
Standard_EXPORT static Standard_Size SizePixelBytes (const Image_Format thePixelFormat);
//! @return bytes reserved per row.
//! Return bytes reserved per row.
//! Could be larger than needed to store packed row (extra bytes for alignment etc.).
inline Standard_Size SizeRowBytes() const
{
return myData.SizeRowBytes;
}
Standard_Size SizeRowBytes() const { return myData.SizeRowBytes; }
//! @return the extra bytes in the row.
inline Standard_Size RowExtraBytes() const
//! Return the extra bytes in the row.
Standard_Size RowExtraBytes() const
{
return SizeRowBytes() - SizeX() * SizePixelBytes();
}
//! Compute the maximal row alignment for current row size.
//! @return maximal row alignment in bytes (up to 16 bytes).
inline Standard_Size MaxRowAligmentBytes() const
{
return myData.MaxRowAligmentBytes();
}
Standard_Size MaxRowAligmentBytes() const { return myData.MaxRowAligmentBytes(); }
//! @return buffer size
inline Standard_Size SizeBytes() const
{
return myData.Size();
}
//! Return number of bytes per 2D slice.
Standard_Size SizeSliceBytes() const { return myData.SizeSliceBytes; }
//! Return buffer size
Standard_Size SizeBytes() const { return myData.Size(); }
public:
//! Access image pixel with specified color type.
//! Indexation starts from 0.
//! This method does not perform any type checks - use on own risk (check Format() before)!
//! WARNING: Input parameters are defined in the decreasing majority following memory layout - e.g. row first, column next.
template <typename ColorType_t>
inline const ColorType_t& Value (const Standard_Size theRow,
const Standard_Size theCol) const
const ColorType_t& Value (Standard_Size theRow,
Standard_Size theCol) const
{
return *reinterpret_cast<const ColorType_t*>(myData.Value (theRow, theCol));
}
//! Access image pixel with specified color type.
//! Indexation starts from 0.
//! This method does not perform any type checks - use on own risk (check Format() before)!
//! WARNING: Input parameters are defined in the decreasing majority following memory layout - e.g. row first, column next.
template <typename ColorType_t>
inline ColorType_t& ChangeValue (const Standard_Size theRow,
const Standard_Size theCol)
ColorType_t& ChangeValue (Standard_Size theRow,
Standard_Size theCol)
{
return *reinterpret_cast<ColorType_t* >(myData.ChangeValue (theRow, theCol));
}
//! Access image pixel as raw data pointer.
//! Indexation starts from 0.
//! This method does not perform any type checks - use on own risk (check Format() before)!
//! WARNING: Input parameters are defined in the decreasing majority following memory layout - e.g. row first, column next.
const Standard_Byte* RawValue (Standard_Size theRow,
Standard_Size theCol) const
{
@@ -282,13 +366,105 @@ public: //! @name low-level API for batch-processing (pixels reading / compariso
}
//! Access image pixel as raw data pointer.
//! Indexation starts from 0.
//! This method does not perform any type checks - use on own risk (check Format() before)!
//! WARNING: Input parameters are defined in the decreasing majority following memory layout - e.g. row first, column next.
Standard_Byte* ChangeRawValue (Standard_Size theRow,
Standard_Size theCol)
{
return myData.ChangeValue (theRow, theCol);
}
//! Access image pixel with specified color type.
//! Indexation starts from 0.
//! This method does not perform any type checks - use on own risk (check Format() before)!
//! WARNING: Input parameters are defined in traditional X, Y order.
template <typename ColorType_t>
const ColorType_t& ValueXY (Standard_Size theX,
Standard_Size theY) const
{
return *reinterpret_cast<const ColorType_t*>(myData.ValueXY (theX, theY));
}
//! Access image pixel with specified color type.
//! Indexation starts from 0.
//! This method does not perform any type checks - use on own risk (check Format() before)!
//! WARNING: Input parameters are defined in traditional X, Y order.
template <typename ColorType_t>
ColorType_t& ChangeValueXY (Standard_Size theX,
Standard_Size theY)
{
return *reinterpret_cast<ColorType_t* >(myData.ChangeValueXY (theX, theY));
}
//! Access image pixel as raw data pointer.
//! Indexation starts from 0.
//! This method does not perform any type checks - use on own risk (check Format() before)!
//! WARNING: Input parameters are defined in traditional X, Y order.
const Standard_Byte* RawValueXY (Standard_Size theX,
Standard_Size theY) const
{
return myData.ValueXY (theX, theY);
}
//! Access image pixel as raw data pointer.
//! Indexation starts from 0.
//! This method does not perform any type checks - use on own risk (check Format() before)!
//! WARNING: Input parameters are defined in traditional X, Y order.
Standard_Byte* ChangeRawValueXY (Standard_Size theX,
Standard_Size theY)
{
return myData.ChangeValueXY (theX, theY);
}
public:
//! Access image pixel with specified color type.
//! Indexation starts from 0.
//! This method does not perform any type checks - use on own risk (check Format() before)!
//! WARNING: Input parameters are defined in traditional X, Y, Z order.
template <typename ColorType_t>
const ColorType_t& ValueXYZ (Standard_Size theX,
Standard_Size theY,
Standard_Size theZ) const
{
return *reinterpret_cast<const ColorType_t*>(myData.ValueXYZ (theX, theY, theZ));
}
//! Access image pixel with specified color type.
//! Indexation starts from 0.
//! This method does not perform any type checks - use on own risk (check Format() before)!
//! WARNING: Input parameters are defined in traditional X, Y, Z order.
template <typename ColorType_t>
ColorType_t& ChangeValueXYZ (Standard_Size theX,
Standard_Size theY,
Standard_Size theZ)
{
return *reinterpret_cast<ColorType_t* >(myData.ChangeValueXYZ (theX, theY, theZ));
}
//! Access image pixel as raw data pointer.
//! Indexation starts from 0.
//! This method does not perform any type checks - use on own risk (check Format() before)!
//! WARNING: Input parameters are defined in traditional X, Y, Z order.
const Standard_Byte* RawValueXYZ (Standard_Size theX,
Standard_Size theY,
Standard_Size theZ) const
{
return myData.ValueXYZ (theX, theY, theZ);
}
//! Access image pixel as raw data pointer.
//! Indexation starts from 0.
//! This method does not perform any type checks - use on own risk (check Format() before)!
//! WARNING: Input parameters are defined in traditional X, Y, Z order.
Standard_Byte* ChangeRawValueXYZ (Standard_Size theX,
Standard_Size theY,
Standard_Size theZ)
{
return myData.ChangeValueXYZ (theX, theY, theZ);
}
public:
//! Convert 16-bit half-float value into 32-bit float (simple conversion).

View File

@@ -18,6 +18,7 @@
#include <Image_Color.hxx>
#include <NCollection_Buffer.hxx>
#include <NCollection_Vec3.hxx>
//! Structure to manage image buffer.
class Image_PixMapData : public NCollection_Buffer
@@ -31,7 +32,9 @@ public:
SizeBPP (0),
SizeX (0),
SizeY (0),
SizeZ (0),
SizeRowBytes (0),
SizeSliceBytes (0),
TopToDown (Standard_Size(-1))
{
//
@@ -44,16 +47,28 @@ public:
const Standard_Size theSizeY,
const Standard_Size theSizeRowBytes,
Standard_Byte* theDataPtr)
{
return Init (theAlloc, theSizeBPP, NCollection_Vec3<Standard_Size> (theSizeX, theSizeY, 1), theSizeRowBytes, theDataPtr);
}
//! Initializer.
bool Init (const Handle(NCollection_BaseAllocator)& theAlloc,
const Standard_Size theSizeBPP,
const NCollection_Vec3<Standard_Size>& theSizeXYZ,
const Standard_Size theSizeRowBytes,
Standard_Byte* theDataPtr)
{
SetAllocator (theAlloc); // will free old data as well
myData = theDataPtr;
myTopRowPtr = NULL;
SizeBPP = theSizeBPP;
SizeX = theSizeX;
SizeY = theSizeY;
SizeRowBytes = theSizeRowBytes != 0 ? theSizeRowBytes : (theSizeX * theSizeBPP);
mySize = SizeRowBytes * SizeY;
SizeX = theSizeXYZ.x();
SizeY = theSizeXYZ.y();
SizeZ = theSizeXYZ.z();
SizeRowBytes = theSizeRowBytes != 0 ? theSizeRowBytes : (SizeX * theSizeBPP);
SizeSliceBytes = SizeRowBytes * SizeY;
mySize = SizeSliceBytes * SizeZ;
if (myData == NULL)
{
Allocate (mySize);
@@ -71,35 +86,93 @@ public:
}
}
//! @return data pointer to requested row (first column).
inline const Standard_Byte* Row (const Standard_Size theRow) const
//! Return data pointer to requested row (first column).
const Standard_Byte* Row (const Standard_Size theRow) const
{
return myTopRowPtr + ptrdiff_t(SizeRowBytes * theRow * TopToDown);
}
//! @return data pointer to requested row (first column).
inline Standard_Byte* ChangeRow (const Standard_Size theRow)
//! Return data pointer to requested row (first column).
Standard_Byte* ChangeRow (const Standard_Size theRow)
{
return myTopRowPtr + ptrdiff_t(SizeRowBytes * theRow * TopToDown);
}
//! @return data pointer to requested position.
inline const Standard_Byte* Value (const Standard_Size theRow,
const Standard_Size theCol) const
//! Return data pointer to requested position.
const Standard_Byte* Value (const Standard_Size theRow,
const Standard_Size theCol) const
{
return myTopRowPtr + ptrdiff_t(SizeRowBytes * theRow * TopToDown) + SizeBPP * theCol;
}
//! @return data pointer to requested position.
inline Standard_Byte* ChangeValue (const Standard_Size theRow,
const Standard_Size theCol)
//! Return data pointer to requested position.
Standard_Byte* ChangeValue (Standard_Size theRow,
Standard_Size theCol)
{
return myTopRowPtr + ptrdiff_t(SizeRowBytes * theRow * TopToDown) + SizeBPP * theCol;
}
//! Return data pointer to requested position.
const Standard_Byte* ValueXY (Standard_Size theX,
Standard_Size theY) const
{
return myTopRowPtr + ptrdiff_t(SizeRowBytes * theY * TopToDown) + SizeBPP * theX;
}
//! Return data pointer to requested position.
Standard_Byte* ChangeValueXY (Standard_Size theX,
Standard_Size theY)
{
return myTopRowPtr + ptrdiff_t(SizeRowBytes * theY * TopToDown) + SizeBPP * theX;
}
public:
//! Return data pointer to requested 2D slice.
const Standard_Byte* Slice (Standard_Size theSlice) const
{
return myData + ptrdiff_t(SizeSliceBytes * theSlice);
}
//! Return data pointer to requested 2D slice.
Standard_Byte* ChangeSlice (Standard_Size theSlice)
{
return myData + ptrdiff_t(SizeSliceBytes * theSlice);
}
//! Return data pointer to requested row (first column).
const Standard_Byte* SliceRow (Standard_Size theSlice,
Standard_Size theRow) const
{
return myTopRowPtr + ptrdiff_t(SizeRowBytes * theRow * TopToDown) + ptrdiff_t(SizeSliceBytes * theSlice);
}
//! Return data pointer to requested row (first column).
Standard_Byte* ChangeSliceRow (Standard_Size theSlice,
Standard_Size theRow)
{
return myTopRowPtr + ptrdiff_t(SizeRowBytes * theRow * TopToDown) + ptrdiff_t(SizeSliceBytes * theSlice);
}
//! Return data pointer to requested position.
const Standard_Byte* ValueXYZ (Standard_Size theX,
Standard_Size theY,
Standard_Size theZ) const
{
return myTopRowPtr + ptrdiff_t(SizeRowBytes * theY * TopToDown) + SizeBPP * theX + ptrdiff_t(SizeSliceBytes * theZ);
}
//! Return data pointer to requested position.
Standard_Byte* ChangeValueXYZ (Standard_Size theX,
Standard_Size theY,
Standard_Size theZ)
{
return myTopRowPtr + ptrdiff_t(SizeRowBytes * theY * TopToDown) + SizeBPP * theX + ptrdiff_t(SizeSliceBytes * theZ);
}
//! Compute the maximal row alignment for current row size.
//! @return maximal row alignment in bytes (up to 16 bytes).
inline Standard_Size MaxRowAligmentBytes() const
Standard_Size MaxRowAligmentBytes() const
{
Standard_Size anAlignment = 2;
for (; anAlignment <= 16; anAlignment <<= 1)
@@ -115,7 +188,7 @@ public:
//! Setup scanlines order in memory - top-down or bottom-up.
//! Drawers should explicitly specify this value if current state IsTopDown() was ignored!
//! @param theIsTopDown top-down flag
inline void SetTopDown (const bool theIsTopDown)
void SetTopDown (const bool theIsTopDown)
{
TopToDown = (theIsTopDown ? 1 : Standard_Size(-1));
myTopRowPtr = ((TopToDown == 1 || myData == NULL)
@@ -128,16 +201,17 @@ protected:
public:
Standard_Size SizeBPP; //!< bytes per pixel
Standard_Size SizeX; //!< width in pixels
Standard_Size SizeY; //!< height in pixels
Standard_Size SizeRowBytes; //!< number of bytes per line (in most cases equal to 3 * sizeX)
Standard_Size TopToDown; //!< image scanlines direction in memory from Top to the Down
Standard_Size SizeBPP; //!< bytes per pixel
Standard_Size SizeX; //!< width in pixels
Standard_Size SizeY; //!< height in pixels
Standard_Size SizeZ; //!< depth in pixels
Standard_Size SizeRowBytes; //!< number of bytes per line (in most cases equal to 3 * sizeX)
Standard_Size SizeSliceBytes; //!< number of bytes per 2D slice
Standard_Size TopToDown; //!< image scanlines direction in memory from Top to the Down
public:
DEFINE_STANDARD_RTTI_INLINE(Image_PixMapData,NCollection_Buffer) // Type definition
DEFINE_STANDARD_RTTIEXT(Image_PixMapData, NCollection_Buffer)
};