0024157: Parallelization of assembly part of BO
[occt.git] / src / Image / Image_PixMap.cxx
CommitLineData
692613e5 1// Created on: 2012-07-18
2// Created by: Kirill GAVRILOV
3// Copyright (c) 2012 OPEN CASCADE SAS
b311480e 4//
5// The content of this file is subject to the Open CASCADE Technology Public
6// License Version 6.5 (the "License"). You may not use the content of this file
7// except in compliance with the License. Please obtain a copy of the License
8// at http://www.opencascade.org and read it completely before using this file.
9//
10// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12//
13// The Original Code and all software distributed under the License is
14// distributed on an "AS IS" basis, without warranty of any kind, and the
15// Initial Developer hereby disclaims all such warranties, including without
16// limitation, any warranties of merchantability, fitness for a particular
17// purpose or non-infringement. Please see the License for the specific terms
18// and conditions governing the rights and limitations under the License.
19
692613e5 20#include <Image_PixMap.hxx>
21
185e6ec0 22#ifdef _MSC_VER
5edb1ac3 23 #include <malloc.h>
185e6ec0 24#elif (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 1)
692613e5 25 #include <mm_malloc.h>
185e6ec0 26#else
27 extern "C" int posix_memalign (void** thePtr, size_t theAlign, size_t theBytesCount);
498ce577 28#endif
7fd59977 29
692613e5 30template<typename TypePtr>
31inline TypePtr MemAllocAligned (const Standard_Size& theBytesCount,
32 const Standard_Size& theAlign = 16)
33{
34#if defined(_MSC_VER)
35 return (TypePtr )_aligned_malloc (theBytesCount, theAlign);
185e6ec0 36#elif (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 1)
692613e5 37 return (TypePtr ) _mm_malloc (theBytesCount, theAlign);
185e6ec0 38#else
39 void* aPtr;
40 if (posix_memalign (&aPtr, theAlign, theBytesCount))
41 {
42 aPtr = NULL;
43 }
44 return (TypePtr )aPtr;
692613e5 45#endif
46}
7fd59977 47
692613e5 48inline void MemFreeAligned (void* thePtrAligned)
49{
50#if defined(_MSC_VER)
51 _aligned_free (thePtrAligned);
185e6ec0 52#elif (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 1)
692613e5 53 _mm_free (thePtrAligned);
185e6ec0 54#else
55 free (thePtrAligned);
692613e5 56#endif
57}
7fd59977 58
692613e5 59IMPLEMENT_STANDARD_HANDLE (Image_PixMap, Standard_Transient)
60IMPLEMENT_STANDARD_RTTIEXT(Image_PixMap, Standard_Transient)
7fd59977 61
692613e5 62// =======================================================================
63// function : Image_PixMap
64// purpose :
65// =======================================================================
66Image_PixMap::Image_PixMap()
67: myImgFormat (Image_PixMap::ImgGray),
68 myIsOwnPointer (true)
69{
70 memset (&myData, 0, sizeof(myData));
71 myData.mySizeBPP = 1;
72 myData.myTopToDown = 1;
73 setFormat (Image_PixMap::ImgGray);
74}
7fd59977 75
692613e5 76// =======================================================================
77// function : ~Image_PixMap
78// purpose :
79// =======================================================================
80Image_PixMap::~Image_PixMap()
81{
82 Clear();
83}
7fd59977 84
692613e5 85Standard_Size Image_PixMap::SizePixelBytes (const Image_PixMap::ImgFormat thePixelFormat)
7fd59977 86{
692613e5 87 switch (thePixelFormat)
7fd59977 88 {
692613e5 89 case ImgGrayF:
90 return sizeof(float);
91 case ImgRGBAF:
92 case ImgBGRAF:
93 return sizeof(float) * 4;
94 case ImgRGBF:
95 case ImgBGRF:
96 return sizeof(float) * 3;
97 case ImgRGBA:
98 case ImgBGRA:
99 return 4;
100 case ImgRGB32:
101 case ImgBGR32:
102 return 4;
103 case ImgRGB:
104 case ImgBGR:
105 return 3;
106 case ImgGray:
7fd59977 107 default:
692613e5 108 return 1;
7fd59977 109 }
7fd59977 110}
111
692613e5 112// =======================================================================
113// function : setFormat
114// purpose :
115// =======================================================================
116void Image_PixMap::setFormat (Image_PixMap::ImgFormat thePixelFormat)
7fd59977 117{
692613e5 118 myImgFormat = thePixelFormat;
119 myData.mySizeBPP = SizePixelBytes (myImgFormat);
7fd59977 120}
121
692613e5 122// =======================================================================
123// function : setTopDown
124// purpose :
125// =======================================================================
126void Image_PixMap::setTopDown()
7fd59977 127{
692613e5 128 myData.myTopRowPtr = ((myData.myTopToDown == 1 || myData.myDataPtr == NULL)
129 ? myData.myDataPtr : (myData.myDataPtr + myData.mySizeRowBytes * (myData.mySizeY - 1)));
7fd59977 130}
131
692613e5 132// =======================================================================
133// function : InitWrapper
134// purpose :
135// =======================================================================
136bool Image_PixMap::InitWrapper (Image_PixMap::ImgFormat thePixelFormat,
137 Standard_Byte* theDataPtr,
138 const Standard_Size theSizeX,
139 const Standard_Size theSizeY,
140 const Standard_Size theSizeRowBytes)
7fd59977 141{
692613e5 142 Clear (thePixelFormat);
143 if ((theSizeX == 0) || (theSizeY == 0) || (theDataPtr == NULL))
7fd59977 144 {
692613e5 145 return false;
7fd59977 146 }
692613e5 147 myData.mySizeX = theSizeX;
148 myData.mySizeY = theSizeY;
149 myData.mySizeRowBytes = (theSizeRowBytes != 0) ? theSizeRowBytes : (theSizeX * myData.mySizeBPP);
150 myData.myDataPtr = theDataPtr;
151 myIsOwnPointer = false;
152 setTopDown();
153 return true;
154}
7fd59977 155
692613e5 156// =======================================================================
157// function : InitTrash
158// purpose :
159// =======================================================================
160bool Image_PixMap::InitTrash (Image_PixMap::ImgFormat thePixelFormat,
161 const Standard_Size theSizeX,
162 const Standard_Size theSizeY,
163 const Standard_Size theSizeRowBytes)
164{
165 Clear (thePixelFormat);
166 if ((theSizeX == 0) || (theSizeY == 0))
7fd59977 167 {
692613e5 168 return false;
7fd59977 169 }
692613e5 170 myData.mySizeX = theSizeX;
171 myData.mySizeY = theSizeY;
172 myData.mySizeRowBytes = myData.mySizeX * myData.mySizeBPP;
173 if (theSizeRowBytes > myData.mySizeRowBytes)
7fd59977 174 {
692613e5 175 // use argument only if it greater
176 myData.mySizeRowBytes = theSizeRowBytes;
7fd59977 177 }
692613e5 178 myData.myDataPtr = MemAllocAligned<Standard_Byte*> (SizeBytes());
179 myIsOwnPointer = true;
180 setTopDown();
181 return myData.myDataPtr != NULL;
7fd59977 182}
183
692613e5 184// =======================================================================
185// function : InitZero
186// purpose :
187// =======================================================================
188bool Image_PixMap::InitZero (Image_PixMap::ImgFormat thePixelFormat,
189 const Standard_Size theSizeX,
190 const Standard_Size theSizeY,
191 const Standard_Size theSizeRowBytes,
192 const Standard_Byte theValue)
7fd59977 193{
692613e5 194 if (!InitTrash (thePixelFormat, theSizeX, theSizeY, theSizeRowBytes))
195 {
196 return false;
197 }
198 memset (myData.myDataPtr, (int )theValue, SizeBytes());
199 return true;
7fd59977 200}
201
692613e5 202// =======================================================================
203// function : InitCopy
204// purpose :
205// =======================================================================
206bool Image_PixMap::InitCopy (const Image_PixMap& theCopy)
7fd59977 207{
692613e5 208 if (&theCopy == this)
7fd59977 209 {
692613e5 210 // self-copying disallowed
211 return false;
7fd59977 212 }
692613e5 213 if (InitTrash (theCopy.myImgFormat, theCopy.myData.mySizeX, theCopy.myData.mySizeY, theCopy.myData.mySizeRowBytes))
214 {
215 memcpy (myData.myDataPtr, theCopy.myData.myDataPtr, theCopy.SizeBytes());
216 return true;
217 }
218 return false;
7fd59977 219}
220
85e096c3 221// =======================================================================
692613e5 222// function : Clear
85e096c3 223// purpose :
224// =======================================================================
692613e5 225void Image_PixMap::Clear (Image_PixMap::ImgFormat thePixelFormat)
7fd59977 226{
692613e5 227 if (myIsOwnPointer && (myData.myDataPtr != NULL))
228 {
229 MemFreeAligned (myData.myDataPtr);
230 }
231 myData.myDataPtr = myData.myTopRowPtr = NULL;
232 myIsOwnPointer = true;
233 myData.mySizeX = myData.mySizeY = myData.mySizeRowBytes = 0;
234 setFormat (thePixelFormat);
235 myData.myTopToDown = 1;
85e096c3 236}
237
238// =======================================================================
239// function : PixelColor
240// purpose :
241// =======================================================================
242Quantity_Color Image_PixMap::PixelColor (const Standard_Integer theX,
243 const Standard_Integer theY,
244 Quantity_Parameter& theAlpha) const
245{
692613e5 246 if (IsEmpty() ||
247 theX < 0 || (Standard_Size )theX >= myData.mySizeX ||
248 theY < 0 || (Standard_Size )theY >= myData.mySizeY)
7fd59977 249 {
85e096c3 250 theAlpha = 0.0; // transparent
7fd59977 251 return Quantity_Color (0.0, 0.0, 0.0, Quantity_TOC_RGB);
252 }
692613e5 253
254 switch (myImgFormat)
7fd59977 255 {
692613e5 256 case ImgGrayF:
257 {
258 const Standard_ShortReal& aPixel = Value<Standard_ShortReal> (theY, theX);
259 theAlpha = 1.0; // opaque
260 return Quantity_Color (Quantity_Parameter (Standard_Real (aPixel)),
261 Quantity_Parameter (Standard_Real (aPixel)),
262 Quantity_Parameter (Standard_Real (aPixel)),
263 Quantity_TOC_RGB);
264 break;
265 }
266 case ImgRGBAF:
267 {
268 const Image_ColorRGBAF& aPixel = Value<Image_ColorRGBAF> (theY, theX);
269 theAlpha = aPixel.a();
270 return Quantity_Color (Quantity_Parameter (aPixel.r()),
271 Quantity_Parameter (aPixel.g()),
272 Quantity_Parameter (aPixel.b()),
273 Quantity_TOC_RGB);
274 }
275 case ImgBGRAF:
276 {
277 const Image_ColorBGRAF& aPixel = Value<Image_ColorBGRAF> (theY, theX);
278 theAlpha = aPixel.a();
279 return Quantity_Color (Quantity_Parameter (aPixel.r()),
280 Quantity_Parameter (aPixel.g()),
281 Quantity_Parameter (aPixel.b()),
282 Quantity_TOC_RGB);
283 }
284 case ImgRGBF:
285 {
286 const Image_ColorRGBF& aPixel = Value<Image_ColorRGBF> (theY, theX);
287 theAlpha = 1.0; // opaque
288 return Quantity_Color (Quantity_Parameter (aPixel.r()),
289 Quantity_Parameter (aPixel.g()),
290 Quantity_Parameter (aPixel.b()),
291 Quantity_TOC_RGB);
292 }
293 case ImgBGRF:
7fd59977 294 {
692613e5 295 const Image_ColorBGRF& aPixel = Value<Image_ColorBGRF> (theY, theX);
296 theAlpha = 1.0; // opaque
297 return Quantity_Color (Quantity_Parameter (aPixel.r()),
298 Quantity_Parameter (aPixel.g()),
299 Quantity_Parameter (aPixel.b()),
300 Quantity_TOC_RGB);
301 }
302 case ImgRGBA:
303 {
304 const Image_ColorRGBA& aPixel = Value<Image_ColorRGBA> (theY, theX);
305 theAlpha = Standard_Real (aPixel.a()) / 255.0;
306 return Quantity_Color (Quantity_Parameter (Standard_Real (aPixel.r()) / 255.0),
307 Quantity_Parameter (Standard_Real (aPixel.g()) / 255.0),
308 Quantity_Parameter (Standard_Real (aPixel.b()) / 255.0),
309 Quantity_TOC_RGB);
310 }
311 case ImgBGRA:
312 {
313 const Image_ColorBGRA& aPixel = Value<Image_ColorBGRA> (theY, theX);
314 theAlpha = Standard_Real (aPixel.a()) / 255.0;
315 return Quantity_Color (Quantity_Parameter (Standard_Real (aPixel.r()) / 255.0),
316 Quantity_Parameter (Standard_Real (aPixel.g()) / 255.0),
317 Quantity_Parameter (Standard_Real (aPixel.b()) / 255.0),
318 Quantity_TOC_RGB);
319 }
320 case ImgRGB32:
321 {
322 const Image_ColorRGB32& aPixel = Value<Image_ColorRGB32> (theY, theX);
323 theAlpha = 1.0; // opaque
324 return Quantity_Color (Quantity_Parameter (Standard_Real (aPixel.r()) / 255.0),
325 Quantity_Parameter (Standard_Real (aPixel.g()) / 255.0),
326 Quantity_Parameter (Standard_Real (aPixel.b()) / 255.0),
327 Quantity_TOC_RGB);
328 }
329 case ImgBGR32:
330 {
331 const Image_ColorBGR32& aPixel = Value<Image_ColorBGR32> (theY, theX);
332 theAlpha = 1.0; // opaque
333 return Quantity_Color (Quantity_Parameter (Standard_Real (aPixel.r()) / 255.0),
334 Quantity_Parameter (Standard_Real (aPixel.g()) / 255.0),
335 Quantity_Parameter (Standard_Real (aPixel.b()) / 255.0),
336 Quantity_TOC_RGB);
337 }
338 case ImgRGB:
339 {
340 const Image_ColorRGB& aPixel = Value<Image_ColorRGB> (theY, theX);
341 theAlpha = 1.0; // opaque
342 return Quantity_Color (Quantity_Parameter (Standard_Real (aPixel.r()) / 255.0),
343 Quantity_Parameter (Standard_Real (aPixel.g()) / 255.0),
344 Quantity_Parameter (Standard_Real (aPixel.b()) / 255.0),
345 Quantity_TOC_RGB);
346 }
347 case ImgBGR:
348 {
349 const Image_ColorBGR& aPixel = Value<Image_ColorBGR> (theY, theX);
350 theAlpha = 1.0; // opaque
351 return Quantity_Color (Quantity_Parameter (Standard_Real (aPixel.r()) / 255.0),
352 Quantity_Parameter (Standard_Real (aPixel.g()) / 255.0),
353 Quantity_Parameter (Standard_Real (aPixel.b()) / 255.0),
354 Quantity_TOC_RGB);
355 }
356 case ImgGray:
357 {
358 const Standard_Byte& aPixel = Value<Standard_Byte> (theY, theX);
359 theAlpha = 1.0; // opaque
360 return Quantity_Color (Quantity_Parameter (Standard_Real (aPixel) / 255.0),
361 Quantity_Parameter (Standard_Real (aPixel) / 255.0),
362 Quantity_Parameter (Standard_Real (aPixel) / 255.0),
363 Quantity_TOC_RGB);
364 }
365 default:
366 {
367 // not supported image type
368 theAlpha = 0.0; // transparent
369 return Quantity_Color (0.0, 0.0, 0.0, Quantity_TOC_RGB);
7fd59977 370 }
371 }
7fd59977 372}