0026936: Drawbacks of inlining in new type system in OCCT 7.0 -- manual
[occt.git] / src / Graphic3d / Graphic3d_MarkerImage.cxx
CommitLineData
a577aaab 1// Created on: 2013-06-25
2// Created by: Dmitry BOBYLEV
d5f74e42 3// Copyright (c) 2013-2014 OPEN CASCADE SAS
a577aaab 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
a577aaab 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
a577aaab 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
a577aaab 15
16#include <Graphic3d_MarkerImage.hxx>
17
18#include <Image_PixMap.hxx>
19#include <Standard_Atomic.hxx>
20#include <TColStd_HArray1OfByte.hxx>
21
22namespace
23{
24 static volatile Standard_Integer THE_MARKER_IMAGE_COUNTER = 0;
25};
26
a577aaab 27
28// =======================================================================
29// function : Graphic3d_MarkerImage
30// purpose :
31// =======================================================================
32Graphic3d_MarkerImage::Graphic3d_MarkerImage (const Handle(Image_PixMap)& theImage)
c04c30b3 33: myImage (theImage),
a577aaab 34 myMargin (1),
35 myWidth ((Standard_Integer )theImage->Width()),
36 myHeight ((Standard_Integer )theImage->Height())
37{
38 myImageId = TCollection_AsciiString ("Graphic3d_MarkerImage_")
39 + TCollection_AsciiString (Standard_Atomic_Increment (&THE_MARKER_IMAGE_COUNTER));
40
41 myImageAlphaId = TCollection_AsciiString ("Graphic3d_MarkerImageAlpha_")
42 + TCollection_AsciiString (THE_MARKER_IMAGE_COUNTER);
43}
44
45// =======================================================================
46// function : Graphic3d_MarkerImage
47// purpose :
48// =======================================================================
49Graphic3d_MarkerImage::Graphic3d_MarkerImage (const Handle(TColStd_HArray1OfByte)& theBitMap,
50 const Standard_Integer& theWidth,
51 const Standard_Integer& theHeight)
52: myBitMap (theBitMap),
a577aaab 53 myMargin (1),
54 myWidth (theWidth),
55 myHeight (theHeight)
56{
57 myImageId = TCollection_AsciiString ("Graphic3d_MarkerImage_")
58 + TCollection_AsciiString (Standard_Atomic_Increment (&THE_MARKER_IMAGE_COUNTER));
59
60 myImageAlphaId = TCollection_AsciiString ("Graphic3d_MarkerImageAlpha_")
61 + TCollection_AsciiString (THE_MARKER_IMAGE_COUNTER);
62}
63
64// =======================================================================
65// function : GetBitMapArray
66// purpose :
67// =======================================================================
68Handle(TColStd_HArray1OfByte) Graphic3d_MarkerImage::GetBitMapArray (const Standard_Real& theAlphaValue) const
69{
70 if (!myBitMap.IsNull())
71 {
72 return myBitMap;
73 }
74
75 Handle(TColStd_HArray1OfByte) aBitMap;
76 if (myImage.IsNull())
77 {
78 return aBitMap;
79 }
80
81 const Standard_Integer aNumOfBytesInRow = (Standard_Integer )(myImage->Width() / 8) + (myImage->Width() % 8 ? 1 : 0);
82 const Standard_Integer aNumOfBytes = (Standard_Integer )(aNumOfBytesInRow * myImage->Height());
83 const Standard_Integer aHeight = (Standard_Integer )myImage->Height();
84 const Standard_Integer aWidth = (Standard_Integer )myImage->Width();
85 aBitMap = new TColStd_HArray1OfByte (0, aNumOfBytes - 1);
86 aBitMap->Init (0);
87 for (Standard_Integer aRow = 0; aRow < aHeight; aRow++)
88 {
89 for (Standard_Integer aColumn = 0; aColumn < aWidth; aColumn++)
90 {
91 Quantity_Parameter anAlphaValue;
92 Quantity_Color aColor = myImage->PixelColor (aColumn, aRow, anAlphaValue);
93 Standard_Boolean aBitOn = Standard_False;
94
076ca35c 95 if (myImage->Format() == Image_PixMap::ImgAlpha)
96 {
97 aBitOn = anAlphaValue > theAlphaValue;
98 }
99 else if (myImage->Format() == Image_PixMap::ImgGray)
a577aaab 100 {
101 aBitOn = aColor.Red() > theAlphaValue;
102 }
103 else
104 {
105 aBitOn = anAlphaValue > theAlphaValue;
106 }
107
008aef40 108 Standard_Integer anIndex = aNumOfBytesInRow * aRow + aColumn / 8;
109 aBitMap->SetValue (anIndex, (Standard_Byte)(aBitMap->Value (anIndex) +
110 (aBitOn ? (0x80 >> (aColumn % 8)) : 0)));
a577aaab 111 }
112 }
113
114 return aBitMap;
115}
116
117// =======================================================================
118// function : GetImage
119// purpose :
120// =======================================================================
121const Handle(Image_PixMap)& Graphic3d_MarkerImage::GetImage()
122{
123 if (!myImage.IsNull())
124 {
125 return myImage;
126 }
127
128 if (myBitMap.IsNull())
129 {
130 return myImage;
131 }
132
133 // Converting a byte array to bitmap image. Row and column offsets are used
134 // to store bitmap in a square image, so the image will not be stretched
135 // when rendering with point sprites.
136 const Standard_Integer aNumOfBytesInRow = myWidth / 8 + (myWidth % 8 ? 1 : 0);
137 const Standard_Integer aSize = Max (myWidth, myHeight);
138 const Standard_Integer aRowOffset = (aSize - myHeight) / 2 + myMargin;
139 const Standard_Integer aColumnOffset = (aSize - myWidth ) / 2 + myMargin;
140 const Standard_Integer aLowerIndex = myBitMap->Lower();
141
142 myImage = new Image_PixMap();
076ca35c 143 myImage->InitZero (Image_PixMap::ImgAlpha, aSize + myMargin * 2, aSize + myMargin * 2);
a577aaab 144 for (Standard_Integer aRowIter = 0; aRowIter < myHeight; aRowIter++)
145 {
146 Standard_Byte* anImageRow = myImage->ChangeRow (aRowIter + aRowOffset);
147 for (Standard_Integer aColumnIter = 0; aColumnIter < myWidth; aColumnIter++)
148 {
149 Standard_Boolean aBitOn = myBitMap->Value (aLowerIndex + aNumOfBytesInRow * aRowIter + aColumnIter / 8) & (0x80 >> (aColumnIter % 8));
150 anImageRow[aColumnIter + aColumnOffset] = aBitOn ? 255 : 0;
151 }
152 }
153
154 return myImage;
155}
156
157// =======================================================================
158// function : GetImageAlpha
159// purpose :
160// =======================================================================
161const Handle(Image_PixMap)& Graphic3d_MarkerImage::GetImageAlpha()
162{
163 if (!myImageAlpha.IsNull())
164 {
165 return myImageAlpha;
166 }
167
168 if (!myImage.IsNull())
169 {
076ca35c 170 if (myImage->Format() == Image_PixMap::ImgGray
171 || myImage->Format() == Image_PixMap::ImgAlpha)
a577aaab 172 {
173 myImageAlpha = myImage;
174 }
175 else
176 {
177 myImageAlpha = new Image_PixMap();
076ca35c 178 myImageAlpha->InitZero (Image_PixMap::ImgAlpha, myImage->Width(), myImage->Height());
a577aaab 179 myImageAlpha->SetTopDown (Standard_False);
180 Quantity_Parameter anAlpha;
498ce76b 181 for (Standard_Size aRowIter = 0; aRowIter < myImage->Height(); aRowIter++)
a577aaab 182 {
183 Standard_Byte* anImageRow = myImageAlpha->ChangeRow (aRowIter);
498ce76b 184 for (Standard_Size aColumnIter = 0; aColumnIter < myImage->Width(); aColumnIter++)
a577aaab 185 {
7dc9e047 186 myImage->PixelColor ((Standard_Integer)aColumnIter, (Standard_Integer)aRowIter, anAlpha);
a577aaab 187 anImageRow[aColumnIter] = Standard_Byte (255.0 * anAlpha);
188 }
189 }
190 }
191 }
192
193 return myImageAlpha;
194}
195
196// =======================================================================
197// function : GetImageId
198// purpose :
199// =======================================================================
200const TCollection_AsciiString& Graphic3d_MarkerImage::GetImageId() const
201{
202 return myImageId;
203}
204
205// =======================================================================
206// function : GetImageAlphaId
207// purpose :
208// =======================================================================
209const TCollection_AsciiString& Graphic3d_MarkerImage::GetImageAlphaId() const
210{
211 return myImageAlphaId;
212}
213
214// =======================================================================
215// function : GetTextureSize
216// purpose :
217// =======================================================================
218void Graphic3d_MarkerImage::GetTextureSize (Standard_Integer& theWidth,
219 Standard_Integer& theHeight) const
220{
221 theWidth = myWidth;
222 theHeight = myHeight;
223}