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