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:
@@ -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;
|
||||
}
|
||||
|
@@ -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).
|
||||
|
@@ -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)
|
||||
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user