mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
0024534: Improve design of Image_PixMap class
Remove template methods Image_PixMap::EditData(), ::ReadData(). Add template method Image_PixMap::ChangeValue(). Remove redundant parameter for Image_PixMap::Clear() method. Make Image_PixMapData non-template class. Introduce NCollection_Buffer.
This commit is contained in:
@@ -201,18 +201,17 @@ bool Image_AlienPixMap::InitCopy (const Image_PixMap& theCopy)
|
|||||||
|
|
||||||
if (myImgFormat == theCopy.Format())
|
if (myImgFormat == theCopy.Format())
|
||||||
{
|
{
|
||||||
if (myData.mySizeRowBytes == theCopy.SizeRowBytes()
|
if (SizeRowBytes() == theCopy.SizeRowBytes()
|
||||||
&& myData.myTopToDown == theCopy.TopDownInc())
|
&& TopDownInc() == theCopy.TopDownInc())
|
||||||
{
|
{
|
||||||
// copy with one call
|
// copy with one call
|
||||||
memcpy (myData.myDataPtr, theCopy.Data(), theCopy.SizeBytes());
|
memcpy (ChangeData(), theCopy.Data(), std::min (SizeBytes(), theCopy.SizeBytes()));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy row-by-row
|
// copy row-by-row
|
||||||
const Standard_Size aRowSizeBytes = (myData.mySizeRowBytes > theCopy.SizeRowBytes())
|
const Standard_Size aRowSizeBytes = std::min (SizeRowBytes(), theCopy.SizeRowBytes());
|
||||||
? theCopy.SizeRowBytes() : myData.mySizeRowBytes;
|
for (Standard_Size aRow = 0; aRow < myData.SizeY; ++aRow)
|
||||||
for (Standard_Size aRow = 0; aRow < myData.mySizeY; ++aRow)
|
|
||||||
{
|
{
|
||||||
memcpy (ChangeRow (aRow), theCopy.Row (aRow), aRowSizeBytes);
|
memcpy (ChangeRow (aRow), theCopy.Row (aRow), aRowSizeBytes);
|
||||||
}
|
}
|
||||||
@@ -228,9 +227,9 @@ bool Image_AlienPixMap::InitCopy (const Image_PixMap& theCopy)
|
|||||||
// function : Clear
|
// function : Clear
|
||||||
// purpose :
|
// purpose :
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
void Image_AlienPixMap::Clear (ImgFormat thePixelFormat)
|
void Image_AlienPixMap::Clear()
|
||||||
{
|
{
|
||||||
Image_PixMap::Clear (thePixelFormat);
|
Image_PixMap::Clear();
|
||||||
#ifdef HAVE_FREEIMAGE
|
#ifdef HAVE_FREEIMAGE
|
||||||
if (myLibImage != NULL)
|
if (myLibImage != NULL)
|
||||||
{
|
{
|
||||||
@@ -383,12 +382,11 @@ bool Image_AlienPixMap::Save (const TCollection_AsciiString& theFileName)
|
|||||||
|| Format() == Image_PixMap::ImgRGB32)
|
|| Format() == Image_PixMap::ImgRGB32)
|
||||||
{
|
{
|
||||||
// stupid FreeImage treats reserved byte as alpha if some bytes not set to 0xFF
|
// stupid FreeImage treats reserved byte as alpha if some bytes not set to 0xFF
|
||||||
Image_PixMapData<Image_ColorRGB32>& aData = Image_PixMap::EditData<Image_ColorRGB32>();
|
|
||||||
for (Standard_Size aRow = 0; aRow < SizeY(); ++aRow)
|
for (Standard_Size aRow = 0; aRow < SizeY(); ++aRow)
|
||||||
{
|
{
|
||||||
for (Standard_Size aCol = 0; aCol < SizeX(); ++aCol)
|
for (Standard_Size aCol = 0; aCol < SizeX(); ++aCol)
|
||||||
{
|
{
|
||||||
aData.ChangeValue (aRow, aCol).a_() = 0xFF;
|
myData.ChangeValue (aRow, aCol)[3] = 0xFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -61,7 +61,7 @@ public:
|
|||||||
Standard_EXPORT virtual bool InitCopy (const Image_PixMap& theCopy);
|
Standard_EXPORT virtual bool InitCopy (const Image_PixMap& theCopy);
|
||||||
|
|
||||||
//! Method correctly deallocate internal buffer.
|
//! Method correctly deallocate internal buffer.
|
||||||
Standard_EXPORT virtual void Clear (ImgFormat thePixelFormat = ImgGray);
|
Standard_EXPORT virtual void Clear();
|
||||||
|
|
||||||
//! Performs gamma correction on image.
|
//! Performs gamma correction on image.
|
||||||
//! theGamma - gamma value to use; a value of 1.0 leaves the image alone
|
//! theGamma - gamma value to use; a value of 1.0 leaves the image alone
|
||||||
|
@@ -23,22 +23,36 @@
|
|||||||
IMPLEMENT_STANDARD_HANDLE (Image_Diff, Standard_Transient)
|
IMPLEMENT_STANDARD_HANDLE (Image_Diff, Standard_Transient)
|
||||||
IMPLEMENT_STANDARD_RTTIEXT(Image_Diff, Standard_Transient)
|
IMPLEMENT_STANDARD_RTTIEXT(Image_Diff, Standard_Transient)
|
||||||
|
|
||||||
|
//! POD structure for packed RGB color value (3 bytes)
|
||||||
|
struct Image_ColorXXX24
|
||||||
|
{
|
||||||
|
Standard_Byte v[3];
|
||||||
|
typedef Standard_Byte ComponentType_t; //!< Component type
|
||||||
|
static Standard_Integer Length() { return 3; } //!< Returns the number of components
|
||||||
|
};
|
||||||
|
|
||||||
|
inline Image_ColorXXX24 operator- (const Image_ColorXXX24& theA,
|
||||||
|
const Image_ColorXXX24& theB)
|
||||||
|
{
|
||||||
|
return Image_ColorSub3 (theA, theB);
|
||||||
|
}
|
||||||
|
|
||||||
//! Dot squared for difference of two colors
|
//! Dot squared for difference of two colors
|
||||||
inline Standard_Integer dotSquared (const Image_ColorRGB& theColor)
|
inline Standard_Integer dotSquared (const Image_ColorXXX24& theColor)
|
||||||
{
|
{
|
||||||
// explicitly convert to integer
|
// explicitly convert to integer
|
||||||
const Standard_Integer r = theColor.r();
|
const Standard_Integer r = theColor.v[0];
|
||||||
const Standard_Integer g = theColor.g();
|
const Standard_Integer g = theColor.v[1];
|
||||||
const Standard_Integer b = theColor.b();
|
const Standard_Integer b = theColor.v[2];
|
||||||
return r * r + g * g + b * b;
|
return r * r + g * g + b * b;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! @return true if pixel is black
|
//! @return true if pixel is black
|
||||||
inline bool isBlack (const Image_ColorRGB& theColor)
|
inline bool isBlack (const Image_ColorXXX24& theColor)
|
||||||
{
|
{
|
||||||
return theColor.r() == 0
|
return theColor.v[0] == 0
|
||||||
&& theColor.g() == 0
|
&& theColor.v[1] == 0
|
||||||
&& theColor.b() == 0;
|
&& theColor.v[2] == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Converts a pixel position (row, column) to one integer value
|
//! Converts a pixel position (row, column) to one integer value
|
||||||
@@ -78,15 +92,15 @@ namespace
|
|||||||
theColCenter + Standard_Size(col_inc));
|
theColCenter + Standard_Size(col_inc));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool isBlack (const Image_PixMapData<Image_ColorRGB>& theData,
|
inline bool isBlack (const Image_PixMap& theData,
|
||||||
const Standard_Size theRowCenter,
|
const Standard_Size theRowCenter,
|
||||||
const Standard_Size theColCenter) const
|
const Standard_Size theColCenter) const
|
||||||
{
|
{
|
||||||
return ::isBlack (theData.Value (theRowCenter + Standard_Size(row_inc),
|
return ::isBlack (theData.Value<Image_ColorXXX24> (theRowCenter + Standard_Size(row_inc),
|
||||||
theColCenter + Standard_Size(col_inc)));
|
theColCenter + Standard_Size(col_inc)));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool isValid (const Image_PixMapData<Image_ColorRGB>& theData,
|
inline bool isValid (const Image_PixMap& theData,
|
||||||
const Standard_Size theRowCenter,
|
const Standard_Size theRowCenter,
|
||||||
const Standard_Size theColCenter) const
|
const Standard_Size theColCenter) const
|
||||||
{
|
{
|
||||||
@@ -173,19 +187,17 @@ Standard_Boolean Image_Diff::Init (const Handle(Image_PixMap)& theImageRef,
|
|||||||
if (theToBlackWhite)
|
if (theToBlackWhite)
|
||||||
{
|
{
|
||||||
// Convert the images to white/black
|
// Convert the images to white/black
|
||||||
const Image_ColorRGB aWhite = {{255, 255, 255}};
|
const Image_ColorXXX24 aWhite = {{255, 255, 255}};
|
||||||
Image_PixMapData<Image_ColorRGB>& aDataRef = myImageRef->EditData<Image_ColorRGB>();
|
for (Standard_Size aRow = 0; aRow < myImageRef->SizeY(); ++aRow)
|
||||||
Image_PixMapData<Image_ColorRGB>& aDataNew = myImageNew->EditData<Image_ColorRGB>();
|
|
||||||
for (Standard_Size aRow = 0; aRow < aDataRef.SizeY(); ++aRow)
|
|
||||||
{
|
{
|
||||||
for (Standard_Size aCol = 0; aCol < aDataRef.SizeY(); ++aCol)
|
for (Standard_Size aCol = 0; aCol < myImageRef->SizeX(); ++aCol)
|
||||||
{
|
{
|
||||||
Image_ColorRGB& aPixel1 = aDataRef.ChangeValue (aRow, aCol);
|
Image_ColorXXX24& aPixel1 = myImageRef->ChangeValue<Image_ColorXXX24> (aRow, aCol);
|
||||||
Image_ColorRGB& aPixel2 = aDataNew.ChangeValue (aRow, aCol);
|
|
||||||
if (!isBlack (aPixel1))
|
if (!isBlack (aPixel1))
|
||||||
{
|
{
|
||||||
aPixel1 = aWhite;
|
aPixel1 = aWhite;
|
||||||
}
|
}
|
||||||
|
Image_ColorXXX24& aPixel2 = myImageNew->ChangeValue<Image_ColorXXX24> (aRow, aCol);
|
||||||
if (!isBlack (aPixel2))
|
if (!isBlack (aPixel2))
|
||||||
{
|
{
|
||||||
aPixel2 = aWhite;
|
aPixel2 = aWhite;
|
||||||
@@ -270,21 +282,19 @@ Standard_Integer Image_Diff::Compare()
|
|||||||
|
|
||||||
// Tolerance of comparison operation for color
|
// Tolerance of comparison operation for color
|
||||||
// Maximum difference between colors (white - black) = 100%
|
// Maximum difference between colors (white - black) = 100%
|
||||||
Image_ColorRGB aDiff = {{255, 255, 255}};
|
Image_ColorXXX24 aDiff = {{255, 255, 255}};
|
||||||
const Standard_Integer aMaxDiffColor = dotSquared (aDiff);
|
const Standard_Integer aMaxDiffColor = dotSquared (aDiff);
|
||||||
const Standard_Integer aDiffThreshold = Standard_Integer(Standard_Real(aMaxDiffColor) * myColorTolerance);
|
const Standard_Integer aDiffThreshold = Standard_Integer(Standard_Real(aMaxDiffColor) * myColorTolerance);
|
||||||
|
|
||||||
// we don't care about RGB/BGR/RGBA/BGRA/RGB32/BGR32 differences
|
// we don't care about RGB/BGR/RGBA/BGRA/RGB32/BGR32 differences
|
||||||
// because we just compute summ of r g b components
|
// because we just compute summ of r g b components
|
||||||
const Image_PixMapData<Image_ColorRGB>& aDataRef = myImageRef->ReadData<Image_ColorRGB>();
|
|
||||||
const Image_PixMapData<Image_ColorRGB>& aDataNew = myImageNew->ReadData<Image_ColorRGB>();
|
|
||||||
|
|
||||||
// compare colors of each pixel
|
// compare colors of each pixel
|
||||||
for (Standard_Size aRow = 0; aRow < myImageRef->SizeY(); ++aRow)
|
for (Standard_Size aRow = 0; aRow < myImageRef->SizeY(); ++aRow)
|
||||||
{
|
{
|
||||||
for (Standard_Size aCol = 0; aCol < myImageRef->SizeX(); ++aCol)
|
for (Standard_Size aCol = 0; aCol < myImageRef->SizeX(); ++aCol)
|
||||||
{
|
{
|
||||||
aDiff = aDataNew.Value (aRow, aCol) - aDataRef.Value (aRow, aCol);
|
aDiff = myImageNew->Value<Image_ColorXXX24> (aRow, aCol) - myImageRef->Value<Image_ColorXXX24> (aRow, aCol);
|
||||||
if (dotSquared (aDiff) > aDiffThreshold)
|
if (dotSquared (aDiff) > aDiffThreshold)
|
||||||
{
|
{
|
||||||
const Standard_Size aValue = pixel2Int (aRow, aCol);
|
const Standard_Size aValue = pixel2Int (aRow, aCol);
|
||||||
@@ -326,8 +336,7 @@ Standard_Boolean Image_Diff::SaveDiffImage (Image_PixMap& theDiffImage) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
Standard_Size aRow, aCol;
|
Standard_Size aRow, aCol;
|
||||||
const Image_ColorRGB aWhite = {{255, 255, 255}};
|
const Image_ColorXXX24 aWhite = {{255, 255, 255}};
|
||||||
Image_PixMapData<Image_ColorRGB>& aDataOut = theDiffImage.EditData<Image_ColorRGB>();
|
|
||||||
|
|
||||||
// initialize black image for dump
|
// initialize black image for dump
|
||||||
memset (theDiffImage.ChangeData(), 0, theDiffImage.SizeBytes());
|
memset (theDiffImage.ChangeData(), 0, theDiffImage.SizeBytes());
|
||||||
@@ -342,7 +351,7 @@ Standard_Boolean Image_Diff::SaveDiffImage (Image_PixMap& theDiffImage) const
|
|||||||
{
|
{
|
||||||
const Standard_Size aValue = myDiffPixels.Value (aPixelId);
|
const Standard_Size aValue = myDiffPixels.Value (aPixelId);
|
||||||
int2Pixel (aValue, aRow, aCol);
|
int2Pixel (aValue, aRow, aCol);
|
||||||
aDataOut.ChangeValue (aRow, aCol) = aWhite;
|
theDiffImage.ChangeValue<Image_ColorXXX24> (aRow, aCol) = aWhite;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Standard_True;
|
return Standard_True;
|
||||||
@@ -361,7 +370,7 @@ Standard_Boolean Image_Diff::SaveDiffImage (Image_PixMap& theDiffImage) const
|
|||||||
aPixelIter.More(); aPixelIter.Next())
|
aPixelIter.More(); aPixelIter.Next())
|
||||||
{
|
{
|
||||||
int2Pixel (aPixelIter.Key(), aRow, aCol);
|
int2Pixel (aPixelIter.Key(), aRow, aCol);
|
||||||
aDataOut.ChangeValue (aRow, aCol) = aWhite;
|
theDiffImage.ChangeValue<Image_ColorXXX24> (aRow, aCol) = aWhite;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -401,8 +410,6 @@ Standard_Integer Image_Diff::ignoreBorderEffect()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Image_PixMapData<Image_ColorRGB>& aDataRef = myImageRef->ReadData<Image_ColorRGB>();
|
|
||||||
|
|
||||||
// allocate groups of different pixels
|
// allocate groups of different pixels
|
||||||
releaseGroupsOfDiffPixels();
|
releaseGroupsOfDiffPixels();
|
||||||
|
|
||||||
@@ -475,7 +482,7 @@ Standard_Integer Image_Diff::ignoreBorderEffect()
|
|||||||
// check all neighbour pixels on presence in the group
|
// check all neighbour pixels on presence in the group
|
||||||
for (Standard_Size aNgbrIter = 0; aNgbrIter < NEIGHBOR_PIXELS_NB; ++aNgbrIter)
|
for (Standard_Size aNgbrIter = 0; aNgbrIter < NEIGHBOR_PIXELS_NB; ++aNgbrIter)
|
||||||
{
|
{
|
||||||
if (NEIGHBOR_PIXELS[aNgbrIter].isValid (aDataRef, aRow1, aCol1)
|
if (NEIGHBOR_PIXELS[aNgbrIter].isValid (*myImageRef, aRow1, aCol1)
|
||||||
&& aGroup->Contains ((Standard_Integer)NEIGHBOR_PIXELS[aNgbrIter].pixel2Int (aRow1, aCol1)))
|
&& aGroup->Contains ((Standard_Integer)NEIGHBOR_PIXELS[aNgbrIter].pixel2Int (aRow1, aCol1)))
|
||||||
{
|
{
|
||||||
++aNeighboursNb;
|
++aNeighboursNb;
|
||||||
@@ -498,8 +505,8 @@ Standard_Integer Image_Diff::ignoreBorderEffect()
|
|||||||
aNeighboursNb = 0;
|
aNeighboursNb = 0;
|
||||||
for (Standard_Size aNgbrIter = 0; aNgbrIter < NEIGHBOR_PIXELS_NB; ++aNgbrIter)
|
for (Standard_Size aNgbrIter = 0; aNgbrIter < NEIGHBOR_PIXELS_NB; ++aNgbrIter)
|
||||||
{
|
{
|
||||||
if ( NEIGHBOR_PIXELS[aNgbrIter].isValid (aDataRef, aRow1, aCol1)
|
if ( NEIGHBOR_PIXELS[aNgbrIter].isValid (*myImageRef, aRow1, aCol1)
|
||||||
&& !NEIGHBOR_PIXELS[aNgbrIter].isBlack (aDataRef, aRow1, aCol1))
|
&& !NEIGHBOR_PIXELS[aNgbrIter].isBlack (*myImageRef, aRow1, aCol1))
|
||||||
{
|
{
|
||||||
++aNeighboursNb;
|
++aNeighboursNb;
|
||||||
}
|
}
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
// commercial license or contractual agreement.
|
// commercial license or contractual agreement.
|
||||||
|
|
||||||
#include <Image_PixMap.hxx>
|
#include <Image_PixMap.hxx>
|
||||||
#include <Standard.hxx>
|
#include <NCollection_AlignedAllocator.hxx>
|
||||||
|
|
||||||
IMPLEMENT_STANDARD_HANDLE (Image_PixMap, Standard_Transient)
|
IMPLEMENT_STANDARD_HANDLE (Image_PixMap, Standard_Transient)
|
||||||
IMPLEMENT_STANDARD_RTTIEXT(Image_PixMap, Standard_Transient)
|
IMPLEMENT_STANDARD_RTTIEXT(Image_PixMap, Standard_Transient)
|
||||||
@@ -24,13 +24,9 @@ IMPLEMENT_STANDARD_RTTIEXT(Image_PixMap, Standard_Transient)
|
|||||||
// purpose :
|
// purpose :
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
Image_PixMap::Image_PixMap()
|
Image_PixMap::Image_PixMap()
|
||||||
: myImgFormat (Image_PixMap::ImgGray),
|
: myImgFormat (Image_PixMap::ImgGray)
|
||||||
myIsOwnPointer (true)
|
|
||||||
{
|
{
|
||||||
memset (&myData, 0, sizeof(myData));
|
//
|
||||||
myData.mySizeBPP = 1;
|
|
||||||
myData.myTopToDown = Standard_Size(-1);
|
|
||||||
setFormat (Image_PixMap::ImgGray);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
@@ -76,17 +72,6 @@ Standard_Size Image_PixMap::SizePixelBytes (const Image_PixMap::ImgFormat thePix
|
|||||||
void Image_PixMap::setFormat (Image_PixMap::ImgFormat thePixelFormat)
|
void Image_PixMap::setFormat (Image_PixMap::ImgFormat thePixelFormat)
|
||||||
{
|
{
|
||||||
myImgFormat = thePixelFormat;
|
myImgFormat = thePixelFormat;
|
||||||
myData.mySizeBPP = SizePixelBytes (myImgFormat);
|
|
||||||
}
|
|
||||||
|
|
||||||
// =======================================================================
|
|
||||||
// function : setTopDown
|
|
||||||
// purpose :
|
|
||||||
// =======================================================================
|
|
||||||
void Image_PixMap::setTopDown()
|
|
||||||
{
|
|
||||||
myData.myTopRowPtr = ((myData.myTopToDown == 1 || myData.myDataPtr == NULL)
|
|
||||||
? myData.myDataPtr : (myData.myDataPtr + myData.mySizeRowBytes * (myData.mySizeY - 1)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
@@ -99,17 +84,16 @@ bool Image_PixMap::InitWrapper (Image_PixMap::ImgFormat thePixelFormat,
|
|||||||
const Standard_Size theSizeY,
|
const Standard_Size theSizeY,
|
||||||
const Standard_Size theSizeRowBytes)
|
const Standard_Size theSizeRowBytes)
|
||||||
{
|
{
|
||||||
Clear (thePixelFormat);
|
Clear();
|
||||||
|
myImgFormat = thePixelFormat;
|
||||||
if ((theSizeX == 0) || (theSizeY == 0) || (theDataPtr == NULL))
|
if ((theSizeX == 0) || (theSizeY == 0) || (theDataPtr == NULL))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
myData.mySizeX = theSizeX;
|
|
||||||
myData.mySizeY = theSizeY;
|
Handle(NCollection_BaseAllocator) anEmptyAlloc;
|
||||||
myData.mySizeRowBytes = (theSizeRowBytes != 0) ? theSizeRowBytes : (theSizeX * myData.mySizeBPP);
|
myData.Init (anEmptyAlloc, Image_PixMap::SizePixelBytes (thePixelFormat),
|
||||||
myData.myDataPtr = theDataPtr;
|
theSizeX, theSizeY, theSizeRowBytes, theDataPtr);
|
||||||
myIsOwnPointer = false;
|
|
||||||
setTopDown();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,23 +106,19 @@ bool Image_PixMap::InitTrash (Image_PixMap::ImgFormat thePixelFormat,
|
|||||||
const Standard_Size theSizeY,
|
const Standard_Size theSizeY,
|
||||||
const Standard_Size theSizeRowBytes)
|
const Standard_Size theSizeRowBytes)
|
||||||
{
|
{
|
||||||
Clear (thePixelFormat);
|
Clear();
|
||||||
|
myImgFormat = thePixelFormat;
|
||||||
if ((theSizeX == 0) || (theSizeY == 0))
|
if ((theSizeX == 0) || (theSizeY == 0))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
myData.mySizeX = theSizeX;
|
|
||||||
myData.mySizeY = theSizeY;
|
|
||||||
myData.mySizeRowBytes = myData.mySizeX * myData.mySizeBPP;
|
|
||||||
if (theSizeRowBytes > myData.mySizeRowBytes)
|
|
||||||
{
|
|
||||||
// use argument only if it greater
|
// use argument only if it greater
|
||||||
myData.mySizeRowBytes = theSizeRowBytes;
|
const Standard_Size aSizeRowBytes = std::max (theSizeRowBytes, theSizeX * SizePixelBytes (thePixelFormat));
|
||||||
}
|
Handle(NCollection_BaseAllocator) anAlloc = new NCollection_AlignedAllocator (16);
|
||||||
myData.myDataPtr = (Standard_Byte* )Standard::AllocateAligned (SizeBytes(), 16);
|
myData.Init (anAlloc, Image_PixMap::SizePixelBytes (thePixelFormat),
|
||||||
myIsOwnPointer = true;
|
theSizeX, theSizeY, aSizeRowBytes, NULL);
|
||||||
setTopDown();
|
return !myData.IsEmpty();
|
||||||
return myData.myDataPtr != NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
@@ -155,7 +135,7 @@ bool Image_PixMap::InitZero (Image_PixMap::ImgFormat thePixelFormat,
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
memset (myData.myDataPtr, (int )theValue, SizeBytes());
|
memset (myData.ChangeData(), (int )theValue, SizeBytes());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,9 +150,9 @@ bool Image_PixMap::InitCopy (const Image_PixMap& theCopy)
|
|||||||
// self-copying disallowed
|
// self-copying disallowed
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (InitTrash (theCopy.myImgFormat, theCopy.myData.mySizeX, theCopy.myData.mySizeY, theCopy.myData.mySizeRowBytes))
|
if (InitTrash (theCopy.myImgFormat, theCopy.SizeX(), theCopy.SizeY(), theCopy.SizeRowBytes()))
|
||||||
{
|
{
|
||||||
memcpy (myData.myDataPtr, theCopy.myData.myDataPtr, theCopy.SizeBytes());
|
memcpy (myData.ChangeData(), theCopy.myData.Data(), theCopy.SizeBytes());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -182,16 +162,11 @@ bool Image_PixMap::InitCopy (const Image_PixMap& theCopy)
|
|||||||
// function : Clear
|
// function : Clear
|
||||||
// purpose :
|
// purpose :
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
void Image_PixMap::Clear (Image_PixMap::ImgFormat thePixelFormat)
|
void Image_PixMap::Clear()
|
||||||
{
|
{
|
||||||
if (myIsOwnPointer && (myData.myDataPtr != NULL))
|
Handle(NCollection_BaseAllocator) anEmptyAlloc;
|
||||||
{
|
myData.Init (anEmptyAlloc, Image_PixMap::SizePixelBytes (myImgFormat),
|
||||||
Standard::FreeAligned (myData.myDataPtr);
|
0, 0, 0, NULL);
|
||||||
}
|
|
||||||
myData.myDataPtr = myData.myTopRowPtr = NULL;
|
|
||||||
myIsOwnPointer = true;
|
|
||||||
myData.mySizeX = myData.mySizeY = myData.mySizeRowBytes = 0;
|
|
||||||
setFormat (thePixelFormat);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
@@ -202,9 +177,9 @@ Quantity_Color Image_PixMap::PixelColor (const Standard_Integer theX,
|
|||||||
const Standard_Integer theY,
|
const Standard_Integer theY,
|
||||||
Quantity_Parameter& theAlpha) const
|
Quantity_Parameter& theAlpha) const
|
||||||
{
|
{
|
||||||
if (IsEmpty() ||
|
if (IsEmpty()
|
||||||
theX < 0 || (Standard_Size )theX >= myData.mySizeX ||
|
|| theX < 0 || (Standard_Size )theX >= SizeX()
|
||||||
theY < 0 || (Standard_Size )theY >= myData.mySizeY)
|
|| theY < 0 || (Standard_Size )theY >= SizeY())
|
||||||
{
|
{
|
||||||
theAlpha = 0.0; // transparent
|
theAlpha = 0.0; // transparent
|
||||||
return Quantity_Color (0.0, 0.0, 0.0, Quantity_TOC_RGB);
|
return Quantity_Color (0.0, 0.0, 0.0, Quantity_TOC_RGB);
|
||||||
|
@@ -62,37 +62,37 @@ public: // high-level API
|
|||||||
//! @return image width in pixels
|
//! @return image width in pixels
|
||||||
inline Standard_Size Width() const
|
inline Standard_Size Width() const
|
||||||
{
|
{
|
||||||
return myData.mySizeX;
|
return myData.SizeX;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! @return image height in pixels
|
//! @return image height in pixels
|
||||||
inline Standard_Size Height() const
|
inline Standard_Size Height() const
|
||||||
{
|
{
|
||||||
return myData.mySizeY;
|
return myData.SizeY;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! @return image width in pixels
|
//! @return image width in pixels
|
||||||
inline Standard_Size SizeX() const
|
inline Standard_Size SizeX() const
|
||||||
{
|
{
|
||||||
return myData.mySizeX;
|
return myData.SizeX;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! @return image height in pixels
|
//! @return image height in pixels
|
||||||
inline Standard_Size SizeY() const
|
inline Standard_Size SizeY() const
|
||||||
{
|
{
|
||||||
return myData.mySizeY;
|
return myData.SizeY;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! @return width / height.
|
//! @return width / height.
|
||||||
inline Standard_Real Ratio() const
|
inline Standard_Real Ratio() const
|
||||||
{
|
{
|
||||||
return (myData.mySizeY > 0) ? (Standard_Real(myData.mySizeX) / Standard_Real(myData.mySizeY)) : 1.0;
|
return (SizeY() > 0) ? (Standard_Real(SizeX()) / Standard_Real(SizeY())) : 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! @return true if data is NULL.
|
//! @return true if data is NULL.
|
||||||
bool IsEmpty() const
|
bool IsEmpty() const
|
||||||
{
|
{
|
||||||
return myData.myDataPtr == NULL;
|
return myData.IsEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Empty constructor. Initialize the NULL image plane.
|
//! Empty constructor. Initialize the NULL image plane.
|
||||||
@@ -148,9 +148,9 @@ public: // high-level API
|
|||||||
const Standard_Byte theValue = 0);
|
const Standard_Byte theValue = 0);
|
||||||
|
|
||||||
//! Method correctly deallocate internal buffer.
|
//! Method correctly deallocate internal buffer.
|
||||||
Standard_EXPORT virtual void Clear (ImgFormat thePixelFormat = ImgGray);
|
Standard_EXPORT virtual void Clear();
|
||||||
|
|
||||||
public: // low-level API for batch-processing (pixels reading / comparison / modification)
|
public: //! @name low-level API for batch-processing (pixels reading / comparison / modification)
|
||||||
|
|
||||||
//! Returns TRUE if image data is stored from Top to the Down.
|
//! Returns TRUE if image data is stored from Top to the Down.
|
||||||
//! By default Bottom Up order is used instead
|
//! By default Bottom Up order is used instead
|
||||||
@@ -163,7 +163,7 @@ public: // low-level API for batch-processing (pixels reading / comparison / mod
|
|||||||
//! @return true if image data is top-down
|
//! @return true if image data is top-down
|
||||||
inline bool IsTopDown() const
|
inline bool IsTopDown() const
|
||||||
{
|
{
|
||||||
return myData.myTopToDown == 1;
|
return myData.TopToDown == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Setup scanlines order in memory - top-down or bottom-up.
|
//! Setup scanlines order in memory - top-down or bottom-up.
|
||||||
@@ -171,27 +171,26 @@ public: // low-level API for batch-processing (pixels reading / comparison / mod
|
|||||||
//! @param theIsTopDown top-down flag
|
//! @param theIsTopDown top-down flag
|
||||||
inline void SetTopDown (const bool theIsTopDown)
|
inline void SetTopDown (const bool theIsTopDown)
|
||||||
{
|
{
|
||||||
myData.myTopToDown = (theIsTopDown ? 1 : Standard_Size(-1));
|
myData.SetTopDown (theIsTopDown);
|
||||||
setTopDown();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Returns +1 if scanlines ordered in Top->Down order in memory and -1 otherwise.
|
//! Returns +1 if scanlines ordered in Top->Down order in memory and -1 otherwise.
|
||||||
//! @return scanline increment for Top->Down iteration
|
//! @return scanline increment for Top->Down iteration
|
||||||
inline Standard_Size TopDownInc() const
|
inline Standard_Size TopDownInc() const
|
||||||
{
|
{
|
||||||
return myData.myTopToDown;
|
return myData.TopToDown;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! @return data pointer for low-level operations (copying entire buffer, parsing with extra tools etc.).
|
//! @return data pointer for low-level operations (copying entire buffer, parsing with extra tools etc.).
|
||||||
inline const Standard_Byte* Data() const
|
inline const Standard_Byte* Data() const
|
||||||
{
|
{
|
||||||
return myData.myDataPtr;
|
return myData.Data();
|
||||||
}
|
}
|
||||||
|
|
||||||
//! @return data pointer for low-level operations (copying entire buffer, parsing with extra tools etc.).
|
//! @return data pointer for low-level operations (copying entire buffer, parsing with extra tools etc.).
|
||||||
inline Standard_Byte* ChangeData()
|
inline Standard_Byte* ChangeData()
|
||||||
{
|
{
|
||||||
return myData.myDataPtr;
|
return myData.ChangeData();
|
||||||
}
|
}
|
||||||
|
|
||||||
//! @return data pointer to requested row (first column).
|
//! @return data pointer to requested row (first column).
|
||||||
@@ -209,7 +208,7 @@ public: // low-level API for batch-processing (pixels reading / comparison / mod
|
|||||||
//! @return bytes reserved for one pixel (may include extra bytes for alignment).
|
//! @return bytes reserved for one pixel (may include extra bytes for alignment).
|
||||||
inline Standard_Size SizePixelBytes() const
|
inline Standard_Size SizePixelBytes() const
|
||||||
{
|
{
|
||||||
return myData.mySizeBPP;
|
return myData.SizeBPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! @return bytes reserved for one pixel (may include extra bytes for alignment).
|
//! @return bytes reserved for one pixel (may include extra bytes for alignment).
|
||||||
@@ -219,13 +218,13 @@ public: // low-level API for batch-processing (pixels reading / comparison / mod
|
|||||||
//! Could be larger than needed to store packed row (extra bytes for alignment etc.).
|
//! Could be larger than needed to store packed row (extra bytes for alignment etc.).
|
||||||
inline Standard_Size SizeRowBytes() const
|
inline Standard_Size SizeRowBytes() const
|
||||||
{
|
{
|
||||||
return myData.mySizeRowBytes;
|
return myData.SizeRowBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! @return the extra bytes in the row.
|
//! @return the extra bytes in the row.
|
||||||
inline Standard_Size RowExtraBytes() const
|
inline Standard_Size RowExtraBytes() const
|
||||||
{
|
{
|
||||||
return myData.mySizeRowBytes - myData.mySizeX * myData.mySizeBPP;
|
return SizeRowBytes() - SizeX() * SizePixelBytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Compute the maximal row alignment for current row size.
|
//! Compute the maximal row alignment for current row size.
|
||||||
@@ -235,31 +234,28 @@ public: // low-level API for batch-processing (pixels reading / comparison / mod
|
|||||||
return myData.MaxRowAligmentBytes();
|
return myData.MaxRowAligmentBytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! @return buffer size
|
||||||
inline Standard_Size SizeBytes() const
|
inline Standard_Size SizeBytes() const
|
||||||
{
|
{
|
||||||
return myData.SizeBytes();
|
return myData.Size();
|
||||||
}
|
|
||||||
|
|
||||||
//! Access image buffer for write/read operations with specified color type.
|
|
||||||
template <typename ColorType_t>
|
|
||||||
inline Image_PixMapData<ColorType_t>& EditData()
|
|
||||||
{
|
|
||||||
return *(Image_PixMapData<ColorType_t>* )&myData;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Access image buffer for read operations with specified color type.
|
|
||||||
template <typename ColorType_t>
|
|
||||||
inline const Image_PixMapData<ColorType_t>& ReadData() const
|
|
||||||
{
|
|
||||||
return *(Image_PixMapData<ColorType_t>* )&myData;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Access image pixel with specified color type.
|
//! Access image pixel with specified color type.
|
||||||
|
//! This method does not perform any type checks - use on own risk (check Format() before)!
|
||||||
template <typename ColorType_t>
|
template <typename ColorType_t>
|
||||||
inline const ColorType_t& Value (const Standard_Size theRow,
|
inline const ColorType_t& Value (const Standard_Size theRow,
|
||||||
const Standard_Size theCol) const
|
const Standard_Size theCol) const
|
||||||
{
|
{
|
||||||
return ((Image_PixMapData<ColorType_t>* )&myData)->Value (theRow, theCol);
|
return *reinterpret_cast<const ColorType_t*>(myData.Value (theRow, theCol));
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Access image pixel with specified color type.
|
||||||
|
//! This method does not perform any type checks - use on own risk (check Format() before)!
|
||||||
|
template <typename ColorType_t>
|
||||||
|
inline ColorType_t& ChangeValue (const Standard_Size theRow,
|
||||||
|
const Standard_Size theCol)
|
||||||
|
{
|
||||||
|
return *reinterpret_cast<ColorType_t* >(myData.ChangeValue (theRow, theCol));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -267,14 +263,10 @@ protected:
|
|||||||
//! Setup pixel format
|
//! Setup pixel format
|
||||||
Standard_EXPORT void setFormat (ImgFormat thePixelFormat);
|
Standard_EXPORT void setFormat (ImgFormat thePixelFormat);
|
||||||
|
|
||||||
//! Auxiliary method to setup myTopRowPtr
|
|
||||||
Standard_EXPORT void setTopDown();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
Image_PixMapData<Standard_Byte> myData;
|
Image_PixMapData myData; //!< data buffer
|
||||||
ImgFormat myImgFormat; //!< pixel format
|
ImgFormat myImgFormat; //!< pixel format
|
||||||
bool myIsOwnPointer; //!< if data was allocated by this class - flag is true
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@@ -17,48 +17,74 @@
|
|||||||
#define _Image_PixMapData_H__
|
#define _Image_PixMapData_H__
|
||||||
|
|
||||||
#include <Image_Color.hxx>
|
#include <Image_Color.hxx>
|
||||||
|
#include <NCollection_Buffer.hxx>
|
||||||
|
|
||||||
//! POD template structure to access image buffer
|
//! Structure to manage image buffer.
|
||||||
template<typename ColorType_t>
|
class Image_PixMapData : public NCollection_Buffer
|
||||||
struct Image_PixMapData
|
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
//! @return data pointer for low-level operations (copying entire buffer, parsing with extra tools etc.).
|
//! Empty constructor.
|
||||||
inline const ColorType_t* Data() const
|
Image_PixMapData()
|
||||||
|
: NCollection_Buffer (Handle(NCollection_BaseAllocator)()),
|
||||||
|
myTopRowPtr (NULL),
|
||||||
|
SizeBPP (0),
|
||||||
|
SizeX (0),
|
||||||
|
SizeY (0),
|
||||||
|
SizeRowBytes (0),
|
||||||
|
TopToDown (Standard_Size(-1))
|
||||||
{
|
{
|
||||||
return (const ColorType_t* )myDataPtr;
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
//! @return data pointer for low-level operations (copying entire buffer, parsing with extra tools etc.).
|
//! Initializer.
|
||||||
inline ColorType_t* ChangeData()
|
void Init (const Handle(NCollection_BaseAllocator)& theAlloc,
|
||||||
|
const Standard_Size theSizeBPP,
|
||||||
|
const Standard_Size theSizeX,
|
||||||
|
const Standard_Size theSizeY,
|
||||||
|
const Standard_Size theSizeRowBytes,
|
||||||
|
Standard_Byte* theDataPtr)
|
||||||
{
|
{
|
||||||
return (ColorType_t* )myDataPtr;
|
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;
|
||||||
|
if (myData == NULL)
|
||||||
|
{
|
||||||
|
Allocate (mySize);
|
||||||
|
}
|
||||||
|
SetTopDown (TopToDown == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! @return data pointer to requested row (first column).
|
//! @return data pointer to requested row (first column).
|
||||||
inline const ColorType_t* Row (const Standard_Size theRow) const
|
inline const Standard_Byte* Row (const Standard_Size theRow) const
|
||||||
{
|
{
|
||||||
return (ColorType_t* )(myTopRowPtr + mySizeRowBytes * theRow * myTopToDown);
|
return myTopRowPtr + SizeRowBytes * theRow * TopToDown;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! @return data pointer to requested row (first column).
|
//! @return data pointer to requested row (first column).
|
||||||
inline ColorType_t* ChangeRow (const Standard_Size theRow)
|
inline Standard_Byte* ChangeRow (const Standard_Size theRow)
|
||||||
{
|
{
|
||||||
return (ColorType_t* )(myTopRowPtr + mySizeRowBytes * theRow * myTopToDown);
|
return myTopRowPtr + SizeRowBytes * theRow * TopToDown;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! @return data pointer to requested position.
|
//! @return data pointer to requested position.
|
||||||
inline const ColorType_t& Value (const Standard_Size theRow,
|
inline const Standard_Byte* Value (const Standard_Size theRow,
|
||||||
const Standard_Size theCol) const
|
const Standard_Size theCol) const
|
||||||
{
|
{
|
||||||
return *(const ColorType_t* )(myTopRowPtr + mySizeRowBytes * theRow * myTopToDown + mySizeBPP * theCol);
|
return myTopRowPtr + SizeRowBytes * theRow * TopToDown + SizeBPP * theCol;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! @return data pointer to requested position.
|
//! @return data pointer to requested position.
|
||||||
inline ColorType_t& ChangeValue (const Standard_Size theRow,
|
inline Standard_Byte* ChangeValue (const Standard_Size theRow,
|
||||||
const Standard_Size theCol)
|
const Standard_Size theCol)
|
||||||
{
|
{
|
||||||
return *(ColorType_t* )(myTopRowPtr + mySizeRowBytes * theRow * myTopToDown + mySizeBPP * theCol);
|
return myTopRowPtr + SizeRowBytes * theRow * TopToDown + SizeBPP * theCol;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Compute the maximal row alignment for current row size.
|
//! Compute the maximal row alignment for current row size.
|
||||||
@@ -68,7 +94,7 @@ struct Image_PixMapData
|
|||||||
Standard_Size anAlignment = 2;
|
Standard_Size anAlignment = 2;
|
||||||
for (; anAlignment <= 16; anAlignment <<= 1)
|
for (; anAlignment <= 16; anAlignment <<= 1)
|
||||||
{
|
{
|
||||||
if ((mySizeRowBytes % anAlignment) != 0 || (Standard_Size(myDataPtr) % anAlignment) != 0)
|
if ((SizeRowBytes % anAlignment) != 0 || (Standard_Size(myData) % anAlignment) != 0)
|
||||||
{
|
{
|
||||||
return (anAlignment >> 1);
|
return (anAlignment >> 1);
|
||||||
}
|
}
|
||||||
@@ -76,34 +102,30 @@ struct Image_PixMapData
|
|||||||
return anAlignment;
|
return anAlignment;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! @return bytes allocated for the whole image plane.
|
//! Setup scanlines order in memory - top-down or bottom-up.
|
||||||
inline Standard_Size SizeBytes() const
|
//! Drawers should explicitly specify this value if current state IsTopDown() was ignored!
|
||||||
|
//! @param theIsTopDown top-down flag
|
||||||
|
inline void SetTopDown (const bool theIsTopDown)
|
||||||
{
|
{
|
||||||
return mySizeRowBytes * mySizeY;
|
TopToDown = (theIsTopDown ? 1 : Standard_Size(-1));
|
||||||
|
myTopRowPtr = ((TopToDown == 1 || myData == NULL)
|
||||||
|
? myData : (myData + SizeRowBytes * (SizeY - 1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
//! @return image width in pixels
|
protected:
|
||||||
inline Standard_Size SizeX() const
|
|
||||||
{
|
|
||||||
return mySizeX;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @return image height in pixels
|
Standard_Byte* myTopRowPtr; //!< pointer to the topmost row (depending on scanlines order in memory)
|
||||||
inline Standard_Size SizeY() const
|
|
||||||
{
|
|
||||||
return mySizeY;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Standard_Byte* myDataPtr; //!< pointer to the data
|
Standard_Size SizeBPP; //!< bytes per pixel
|
||||||
Standard_Byte* myTopRowPtr; //!< pointer to the topmost row (depending on scanlines order in memory)
|
Standard_Size SizeX; //!< width in pixels
|
||||||
Standard_Size mySizeBPP; //!< bytes per pixel
|
Standard_Size SizeY; //!< height in pixels
|
||||||
Standard_Size mySizeX; //!< width in pixels
|
Standard_Size SizeRowBytes; //!< number of bytes per line (in most cases equal to 3 * sizeX)
|
||||||
Standard_Size mySizeY; //!< height in pixels
|
Standard_Size TopToDown; //!< image scanlines direction in memory from Top to the Down
|
||||||
Standard_Size mySizeRowBytes; //!< number of bytes per line (in most cases equal to 3 * sizeX)
|
|
||||||
Standard_Size myTopToDown; //!< image scanlines direction in memory from Top to the Down
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef NCollection_Handle<Image_PixMapData> Handle(Image_PixMapData);
|
||||||
|
|
||||||
#endif // _Image_PixMapData_H__
|
#endif // _Image_PixMapData_H__
|
||||||
|
@@ -695,11 +695,10 @@ Handle(Graphic3d_Texture2D) MeshVS_NodalColorPrsBuilder::CreateTexture() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
anImage->SetTopDown (false);
|
anImage->SetTopDown (false);
|
||||||
Image_PixMapData<Image_ColorRGBA>& aData = anImage->EditData<Image_ColorRGBA>();
|
|
||||||
for (Standard_Size aCol = 0; aCol < Standard_Size(aColorsNb); ++aCol)
|
for (Standard_Size aCol = 0; aCol < Standard_Size(aColorsNb); ++aCol)
|
||||||
{
|
{
|
||||||
const Quantity_Color& aSrcColor = myTextureColorMap.Value (Standard_Integer(aCol) + 1);
|
const Quantity_Color& aSrcColor = myTextureColorMap.Value (Standard_Integer(aCol) + 1);
|
||||||
Image_ColorRGBA& aColor = aData.ChangeValue (0, aCol);
|
Image_ColorRGBA& aColor = anImage->ChangeValue<Image_ColorRGBA> (0, aCol);
|
||||||
aColor.r() = Standard_Byte(255.0 * aSrcColor.Red());
|
aColor.r() = Standard_Byte(255.0 * aSrcColor.Red());
|
||||||
aColor.g() = Standard_Byte(255.0 * aSrcColor.Green());
|
aColor.g() = Standard_Byte(255.0 * aSrcColor.Green());
|
||||||
aColor.b() = Standard_Byte(255.0 * aSrcColor.Blue());
|
aColor.b() = Standard_Byte(255.0 * aSrcColor.Blue());
|
||||||
@@ -719,7 +718,7 @@ Handle(Graphic3d_Texture2D) MeshVS_NodalColorPrsBuilder::CreateTexture() const
|
|||||||
// fill second row
|
// fill second row
|
||||||
for (Standard_Size aCol = (Standard_Size )aColorsNb; aCol < anImage->SizeX(); ++aCol)
|
for (Standard_Size aCol = (Standard_Size )aColorsNb; aCol < anImage->SizeX(); ++aCol)
|
||||||
{
|
{
|
||||||
aData.ChangeValue (0, aCol) = aLastColor;
|
anImage->ChangeValue<Image_ColorRGBA> (0, aCol) = aLastColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Image_ColorRGBA anInvalidColor =
|
const Image_ColorRGBA anInvalidColor =
|
||||||
@@ -731,7 +730,7 @@ Handle(Graphic3d_Texture2D) MeshVS_NodalColorPrsBuilder::CreateTexture() const
|
|||||||
}};
|
}};
|
||||||
for (Standard_Size aCol = 0; aCol < anImage->SizeX(); ++aCol)
|
for (Standard_Size aCol = 0; aCol < anImage->SizeX(); ++aCol)
|
||||||
{
|
{
|
||||||
aData.ChangeValue (1, aCol) = anInvalidColor;
|
anImage->ChangeValue<Image_ColorRGBA> (1, aCol) = anInvalidColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create texture
|
// create texture
|
||||||
|
@@ -91,6 +91,7 @@ NCollection_Haft.h
|
|||||||
NCollection_DefaultHasher.hxx
|
NCollection_DefaultHasher.hxx
|
||||||
NCollection_DefineAlloc.hxx
|
NCollection_DefineAlloc.hxx
|
||||||
|
|
||||||
|
NCollection_Buffer.hxx
|
||||||
NCollection_Vec2.hxx
|
NCollection_Vec2.hxx
|
||||||
NCollection_Vec3.hxx
|
NCollection_Vec3.hxx
|
||||||
NCollection_Vec4.hxx
|
NCollection_Vec4.hxx
|
||||||
|
135
src/NCollection/NCollection_Buffer.hxx
Normal file
135
src/NCollection/NCollection_Buffer.hxx
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
// Created on: 2014-04-01
|
||||||
|
// Created by: Kirill Gavrilov
|
||||||
|
// Copyright (c) 2014 OPEN CASCADE SAS
|
||||||
|
//
|
||||||
|
// This file is part of Open CASCADE Technology software library.
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify it under
|
||||||
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||||
|
// by the Free Software Foundation, with special exception defined in the file
|
||||||
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||||
|
// distribution for complete text of the license and disclaimer of any warranty.
|
||||||
|
//
|
||||||
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||||
|
// commercial license or contractual agreement.
|
||||||
|
|
||||||
|
#ifndef _NCollection_Buffer_HeaderFile
|
||||||
|
#define _NCollection_Buffer_HeaderFile
|
||||||
|
|
||||||
|
#include <NCollection_BaseAllocator.hxx>
|
||||||
|
#include <NCollection_Handle.hxx>
|
||||||
|
|
||||||
|
//! Low-level buffer object.
|
||||||
|
class NCollection_Buffer
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//! Default constructor.
|
||||||
|
//! When theData is NULL but theSize is not 0 than buffer of specified size will be allocated.
|
||||||
|
//! @param theAlloc memory allocator
|
||||||
|
//! @param theSize buffer size
|
||||||
|
//! @param theData buffer data allocated by theAlloc
|
||||||
|
NCollection_Buffer (const Handle(NCollection_BaseAllocator)& theAlloc,
|
||||||
|
const Standard_Size theSize = 0,
|
||||||
|
Standard_Byte* theData = NULL)
|
||||||
|
: myData (NULL),
|
||||||
|
mySize (0),
|
||||||
|
myAllocator (theAlloc)
|
||||||
|
{
|
||||||
|
if (theData != NULL)
|
||||||
|
{
|
||||||
|
myData = theData;
|
||||||
|
mySize = theSize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Allocate (theSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Destructor.
|
||||||
|
virtual ~NCollection_Buffer()
|
||||||
|
{
|
||||||
|
Free();
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @return buffer data
|
||||||
|
const Standard_Byte* Data() const
|
||||||
|
{
|
||||||
|
return myData;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @return buffer data
|
||||||
|
Standard_Byte* ChangeData()
|
||||||
|
{
|
||||||
|
return myData;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @return true if buffer is not allocated
|
||||||
|
bool IsEmpty() const
|
||||||
|
{
|
||||||
|
return myData == NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Return buffer length in bytes.
|
||||||
|
Standard_Size Size() const
|
||||||
|
{
|
||||||
|
return mySize;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @return buffer allocator
|
||||||
|
const Handle(NCollection_BaseAllocator)& Allocator() const
|
||||||
|
{
|
||||||
|
return myAllocator;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Assign new buffer allocator with de-allocation of buffer.
|
||||||
|
void SetAllocator (const Handle(NCollection_BaseAllocator)& theAlloc)
|
||||||
|
{
|
||||||
|
Free();
|
||||||
|
myAllocator = theAlloc;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Allocate the buffer.
|
||||||
|
//! @param theSize buffer length in bytes
|
||||||
|
bool Allocate (const Standard_Size theSize)
|
||||||
|
{
|
||||||
|
Free();
|
||||||
|
mySize = theSize;
|
||||||
|
if (theSize != 0
|
||||||
|
|| !myAllocator.IsNull())
|
||||||
|
{
|
||||||
|
myData = (Standard_Byte* )myAllocator->Allocate (theSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (myData == NULL)
|
||||||
|
{
|
||||||
|
mySize = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! De-allocate buffer.
|
||||||
|
void Free()
|
||||||
|
{
|
||||||
|
if (!myAllocator.IsNull())
|
||||||
|
{
|
||||||
|
myAllocator->Free (myData);
|
||||||
|
}
|
||||||
|
myData = NULL;
|
||||||
|
mySize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
Standard_Byte* myData; //!< data pointer
|
||||||
|
Standard_Size mySize; //!< buffer length in bytes
|
||||||
|
Handle(NCollection_BaseAllocator) myAllocator; //!< buffer allocator
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef NCollection_Handle<NCollection_Buffer> Handle(NCollection_Buffer);
|
||||||
|
|
||||||
|
#endif // _NCollection_Buffer_HeaderFile
|
@@ -1710,8 +1710,6 @@ void OpenGl_AspectMarker::Resources::BuildSprites (const Handle(OpenGl_Workspace
|
|||||||
anImageA = new Image_PixMap();
|
anImageA = new Image_PixMap();
|
||||||
anImage ->InitZero (Image_PixMap::ImgBGRA, aSize, aSize);
|
anImage ->InitZero (Image_PixMap::ImgBGRA, aSize, aSize);
|
||||||
anImageA->InitZero (Image_PixMap::ImgGray, aSize, aSize);
|
anImageA->InitZero (Image_PixMap::ImgGray, aSize, aSize);
|
||||||
Image_PixMapData<Image_ColorBGRA>& aDataBGRA = anImage->EditData<Image_ColorBGRA>();
|
|
||||||
Image_PixMapData<Standard_Byte>& aDataGray = anImageA->EditData<Standard_Byte>();
|
|
||||||
|
|
||||||
// we draw a set of circles
|
// we draw a set of circles
|
||||||
Image_ColorBGRA aColor32;
|
Image_ColorBGRA aColor32;
|
||||||
@@ -1729,8 +1727,8 @@ void OpenGl_AspectMarker::Resources::BuildSprites (const Handle(OpenGl_Workspace
|
|||||||
const Handle(Graphic3d_MarkerImage) aMarker = GetTextureImage (Aspect_TOM_O, aScale);
|
const Handle(Graphic3d_MarkerImage) aMarker = GetTextureImage (Aspect_TOM_O, aScale);
|
||||||
const Handle(Image_PixMap)& aCircle = aMarker->GetImage();
|
const Handle(Image_PixMap)& aCircle = aMarker->GetImage();
|
||||||
|
|
||||||
const Standard_Size aDiffX = (aDataBGRA.SizeX() - aCircle->SizeX()) / 2;
|
const Standard_Size aDiffX = (anImage->SizeX() - aCircle->SizeX()) / 2;
|
||||||
const Standard_Size aDiffY = (aDataBGRA.SizeY() - aCircle->SizeY()) / 2;
|
const Standard_Size aDiffY = (anImage->SizeY() - aCircle->SizeY()) / 2;
|
||||||
for (Standard_Size aRow = 0; aRow < aCircle->SizeY(); ++aRow)
|
for (Standard_Size aRow = 0; aRow < aCircle->SizeY(); ++aRow)
|
||||||
{
|
{
|
||||||
const Standard_Byte* aRowData = aCircle->Row (aRow);
|
const Standard_Byte* aRowData = aCircle->Row (aRow);
|
||||||
@@ -1738,8 +1736,8 @@ void OpenGl_AspectMarker::Resources::BuildSprites (const Handle(OpenGl_Workspace
|
|||||||
{
|
{
|
||||||
if (aRowData[aCol] != 0)
|
if (aRowData[aCol] != 0)
|
||||||
{
|
{
|
||||||
aDataBGRA.ChangeValue (aDiffX + aRow, aDiffY + aCol) = aColor32;
|
anImage ->ChangeValue<Image_ColorBGRA> (aDiffX + aRow, aDiffY + aCol) = aColor32;
|
||||||
aDataGray.ChangeValue (aDiffX + aRow, aDiffY + aCol) = 255;
|
anImageA->ChangeValue<Standard_Byte> (aDiffX + aRow, aDiffY + aCol) = 255;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -859,14 +859,13 @@ void OpenGl_View::CreateBackgroundTexture (const Standard_CString theFilePath,
|
|||||||
}
|
}
|
||||||
|
|
||||||
anImage.SetTopDown (false);
|
anImage.SetTopDown (false);
|
||||||
Image_PixMapData<Image_ColorRGB>& aDataNew = anImage.EditData<Image_ColorRGB>();
|
|
||||||
Quantity_Color aSrcColor;
|
Quantity_Color aSrcColor;
|
||||||
for (Standard_Size aRow = 0; aRow < anImage.SizeY(); ++aRow)
|
for (Standard_Size aRow = 0; aRow < anImage.SizeY(); ++aRow)
|
||||||
{
|
{
|
||||||
for (Standard_Size aCol = 0; aCol < anImage.SizeX(); ++aCol)
|
for (Standard_Size aCol = 0; aCol < anImage.SizeX(); ++aCol)
|
||||||
{
|
{
|
||||||
aSrcColor = anImageLoaded.PixelColor ((Standard_Integer )aCol, (Standard_Integer )aRow);
|
aSrcColor = anImageLoaded.PixelColor ((Standard_Integer )aCol, (Standard_Integer )aRow);
|
||||||
Image_ColorRGB& aColor = aDataNew.ChangeValue (aRow, aCol);
|
Image_ColorRGB& aColor = anImage.ChangeValue<Image_ColorRGB> (aRow, aCol);
|
||||||
aColor.r() = Standard_Byte(255.0 * aSrcColor.Red());
|
aColor.r() = Standard_Byte(255.0 * aSrcColor.Red());
|
||||||
aColor.g() = Standard_Byte(255.0 * aSrcColor.Green());
|
aColor.g() = Standard_Byte(255.0 * aSrcColor.Green());
|
||||||
aColor.b() = Standard_Byte(255.0 * aSrcColor.Blue());
|
aColor.b() = Standard_Byte(255.0 * aSrcColor.Blue());
|
||||||
|
@@ -1771,12 +1771,11 @@ static Standard_Integer OCC24622 (Draw_Interpretor& /*theDi*/, Standard_Integer
|
|||||||
else if (aTextureTypeArg == "2D")
|
else if (aTextureTypeArg == "2D")
|
||||||
{
|
{
|
||||||
anImage->InitTrash (Image_PixMap::ImgRGB, 8, 8);
|
anImage->InitTrash (Image_PixMap::ImgRGB, 8, 8);
|
||||||
Image_PixMapData<Image_ColorRGB>& anImageData = anImage->EditData<Image_ColorRGB>();
|
|
||||||
for (Standard_Integer aRow = 0; aRow < 8; ++aRow)
|
for (Standard_Integer aRow = 0; aRow < 8; ++aRow)
|
||||||
{
|
{
|
||||||
for (Standard_Integer aCol = 0; aCol < 8; ++aCol)
|
for (Standard_Integer aCol = 0; aCol < 8; ++aCol)
|
||||||
{
|
{
|
||||||
anImageData.ChangeValue (aRow, aCol) = aBitmap[aRow];
|
anImage->ChangeValue<Image_ColorRGB> (aRow, aCol) = aBitmap[aRow];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user