0021593: Small improvement
[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
27IMPLEMENT_STANDARD_HANDLE (Graphic3d_MarkerImage, Standard_Transient)
28IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_MarkerImage, Standard_Transient)
29
30// =======================================================================
31// function : Graphic3d_MarkerImage
32// purpose :
33// =======================================================================
34Graphic3d_MarkerImage::Graphic3d_MarkerImage (const Handle(Image_PixMap)& theImage)
35: myBitMap (NULL),
36 myImage (theImage),
37 myImageAlpha (NULL),
38 myMargin (1),
39 myWidth ((Standard_Integer )theImage->Width()),
40 myHeight ((Standard_Integer )theImage->Height())
41{
42 myImageId = TCollection_AsciiString ("Graphic3d_MarkerImage_")
43 + TCollection_AsciiString (Standard_Atomic_Increment (&THE_MARKER_IMAGE_COUNTER));
44
45 myImageAlphaId = TCollection_AsciiString ("Graphic3d_MarkerImageAlpha_")
46 + TCollection_AsciiString (THE_MARKER_IMAGE_COUNTER);
47}
48
49// =======================================================================
50// function : Graphic3d_MarkerImage
51// purpose :
52// =======================================================================
53Graphic3d_MarkerImage::Graphic3d_MarkerImage (const Handle(TColStd_HArray1OfByte)& theBitMap,
54 const Standard_Integer& theWidth,
55 const Standard_Integer& theHeight)
56: myBitMap (theBitMap),
57 myImage (NULL),
58 myImageAlpha (NULL),
59 myMargin (1),
60 myWidth (theWidth),
61 myHeight (theHeight)
62{
63 myImageId = TCollection_AsciiString ("Graphic3d_MarkerImage_")
64 + TCollection_AsciiString (Standard_Atomic_Increment (&THE_MARKER_IMAGE_COUNTER));
65
66 myImageAlphaId = TCollection_AsciiString ("Graphic3d_MarkerImageAlpha_")
67 + TCollection_AsciiString (THE_MARKER_IMAGE_COUNTER);
68}
69
70// =======================================================================
71// function : GetBitMapArray
72// purpose :
73// =======================================================================
74Handle(TColStd_HArray1OfByte) Graphic3d_MarkerImage::GetBitMapArray (const Standard_Real& theAlphaValue) const
75{
76 if (!myBitMap.IsNull())
77 {
78 return myBitMap;
79 }
80
81 Handle(TColStd_HArray1OfByte) aBitMap;
82 if (myImage.IsNull())
83 {
84 return aBitMap;
85 }
86
87 const Standard_Integer aNumOfBytesInRow = (Standard_Integer )(myImage->Width() / 8) + (myImage->Width() % 8 ? 1 : 0);
88 const Standard_Integer aNumOfBytes = (Standard_Integer )(aNumOfBytesInRow * myImage->Height());
89 const Standard_Integer aHeight = (Standard_Integer )myImage->Height();
90 const Standard_Integer aWidth = (Standard_Integer )myImage->Width();
91 aBitMap = new TColStd_HArray1OfByte (0, aNumOfBytes - 1);
92 aBitMap->Init (0);
93 for (Standard_Integer aRow = 0; aRow < aHeight; aRow++)
94 {
95 for (Standard_Integer aColumn = 0; aColumn < aWidth; aColumn++)
96 {
97 Quantity_Parameter anAlphaValue;
98 Quantity_Color aColor = myImage->PixelColor (aColumn, aRow, anAlphaValue);
99 Standard_Boolean aBitOn = Standard_False;
100
101 if (myImage->Format() == Image_PixMap::ImgGray)
102 {
103 aBitOn = aColor.Red() > theAlphaValue;
104 }
105 else
106 {
107 aBitOn = anAlphaValue > theAlphaValue;
108 }
109
008aef40 110 Standard_Integer anIndex = aNumOfBytesInRow * aRow + aColumn / 8;
111 aBitMap->SetValue (anIndex, (Standard_Byte)(aBitMap->Value (anIndex) +
112 (aBitOn ? (0x80 >> (aColumn % 8)) : 0)));
a577aaab 113 }
114 }
115
116 return aBitMap;
117}
118
119// =======================================================================
120// function : GetImage
121// purpose :
122// =======================================================================
123const Handle(Image_PixMap)& Graphic3d_MarkerImage::GetImage()
124{
125 if (!myImage.IsNull())
126 {
127 return myImage;
128 }
129
130 if (myBitMap.IsNull())
131 {
132 return myImage;
133 }
134
135 // Converting a byte array to bitmap image. Row and column offsets are used
136 // to store bitmap in a square image, so the image will not be stretched
137 // when rendering with point sprites.
138 const Standard_Integer aNumOfBytesInRow = myWidth / 8 + (myWidth % 8 ? 1 : 0);
139 const Standard_Integer aSize = Max (myWidth, myHeight);
140 const Standard_Integer aRowOffset = (aSize - myHeight) / 2 + myMargin;
141 const Standard_Integer aColumnOffset = (aSize - myWidth ) / 2 + myMargin;
142 const Standard_Integer aLowerIndex = myBitMap->Lower();
143
144 myImage = new Image_PixMap();
145 myImage->InitZero (Image_PixMap::ImgGray, aSize + myMargin * 2, aSize + myMargin * 2);
146 for (Standard_Integer aRowIter = 0; aRowIter < myHeight; aRowIter++)
147 {
148 Standard_Byte* anImageRow = myImage->ChangeRow (aRowIter + aRowOffset);
149 for (Standard_Integer aColumnIter = 0; aColumnIter < myWidth; aColumnIter++)
150 {
151 Standard_Boolean aBitOn = myBitMap->Value (aLowerIndex + aNumOfBytesInRow * aRowIter + aColumnIter / 8) & (0x80 >> (aColumnIter % 8));
152 anImageRow[aColumnIter + aColumnOffset] = aBitOn ? 255 : 0;
153 }
154 }
155
156 return myImage;
157}
158
159// =======================================================================
160// function : GetImageAlpha
161// purpose :
162// =======================================================================
163const Handle(Image_PixMap)& Graphic3d_MarkerImage::GetImageAlpha()
164{
165 if (!myImageAlpha.IsNull())
166 {
167 return myImageAlpha;
168 }
169
170 if (!myImage.IsNull())
171 {
172 if (myImage->Format() == Image_PixMap::ImgGray)
173 {
174 myImageAlpha = myImage;
175 }
176 else
177 {
178 myImageAlpha = new Image_PixMap();
179 myImageAlpha->InitZero (Image_PixMap::ImgGray, myImage->Width(), myImage->Height());
180 myImageAlpha->SetTopDown (Standard_False);
181 Quantity_Parameter anAlpha;
498ce76b 182 for (Standard_Size aRowIter = 0; aRowIter < myImage->Height(); aRowIter++)
a577aaab 183 {
184 Standard_Byte* anImageRow = myImageAlpha->ChangeRow (aRowIter);
498ce76b 185 for (Standard_Size aColumnIter = 0; aColumnIter < myImage->Width(); aColumnIter++)
a577aaab 186 {
7dc9e047 187 myImage->PixelColor ((Standard_Integer)aColumnIter, (Standard_Integer)aRowIter, anAlpha);
a577aaab 188 anImageRow[aColumnIter] = Standard_Byte (255.0 * anAlpha);
189 }
190 }
191 }
192 }
193
194 return myImageAlpha;
195}
196
197// =======================================================================
198// function : GetImageId
199// purpose :
200// =======================================================================
201const TCollection_AsciiString& Graphic3d_MarkerImage::GetImageId() const
202{
203 return myImageId;
204}
205
206// =======================================================================
207// function : GetImageAlphaId
208// purpose :
209// =======================================================================
210const TCollection_AsciiString& Graphic3d_MarkerImage::GetImageAlphaId() const
211{
212 return myImageAlphaId;
213}
214
215// =======================================================================
216// function : GetTextureSize
217// purpose :
218// =======================================================================
219void Graphic3d_MarkerImage::GetTextureSize (Standard_Integer& theWidth,
220 Standard_Integer& theHeight) const
221{
222 theWidth = myWidth;
223 theHeight = myHeight;
224}