0024405: TKernel - add aligned allocator class Standard_MMgrAligned
[occt.git] / src / Image / Image_PixMap.cxx
1 // Created on: 2010-07-18
2 // Created by: Kirill GAVRILOV
3 // Copyright (c) 2010-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
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
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.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <Image_PixMap.hxx>
17 #include <Standard.hxx>
18
19 IMPLEMENT_STANDARD_HANDLE (Image_PixMap, Standard_Transient)
20 IMPLEMENT_STANDARD_RTTIEXT(Image_PixMap, Standard_Transient)
21
22 // =======================================================================
23 // function : Image_PixMap
24 // purpose  :
25 // =======================================================================
26 Image_PixMap::Image_PixMap()
27 : myImgFormat (Image_PixMap::ImgGray),
28   myIsOwnPointer (true)
29 {
30   memset (&myData, 0, sizeof(myData));
31   myData.mySizeBPP   = 1;
32   myData.myTopToDown = Standard_Size(-1);
33   setFormat (Image_PixMap::ImgGray);
34 }
35
36 // =======================================================================
37 // function : ~Image_PixMap
38 // purpose  :
39 // =======================================================================
40 Image_PixMap::~Image_PixMap()
41 {
42   Clear();
43 }
44
45 Standard_Size Image_PixMap::SizePixelBytes (const Image_PixMap::ImgFormat thePixelFormat)
46 {
47   switch (thePixelFormat)
48   {
49     case ImgGrayF:
50       return sizeof(float);
51     case ImgRGBAF:
52     case ImgBGRAF:
53       return sizeof(float) * 4;
54     case ImgRGBF:
55     case ImgBGRF:
56       return sizeof(float) * 3;
57     case ImgRGBA:
58     case ImgBGRA:
59       return 4;
60     case ImgRGB32:
61     case ImgBGR32:
62       return 4;
63     case ImgRGB:
64     case ImgBGR:
65       return 3;
66     case ImgGray:
67     default:
68       return 1;
69   }
70 }
71
72 // =======================================================================
73 // function : setFormat
74 // purpose  :
75 // =======================================================================
76 void Image_PixMap::setFormat (Image_PixMap::ImgFormat thePixelFormat)
77 {
78   myImgFormat      = thePixelFormat;
79   myData.mySizeBPP = SizePixelBytes (myImgFormat);
80 }
81
82 // =======================================================================
83 // function : setTopDown
84 // purpose  :
85 // =======================================================================
86 void Image_PixMap::setTopDown()
87 {
88   myData.myTopRowPtr = ((myData.myTopToDown == 1 || myData.myDataPtr == NULL)
89                      ? myData.myDataPtr : (myData.myDataPtr + myData.mySizeRowBytes * (myData.mySizeY - 1)));
90 }
91
92 // =======================================================================
93 // function : InitWrapper
94 // purpose  :
95 // =======================================================================
96 bool Image_PixMap::InitWrapper (Image_PixMap::ImgFormat thePixelFormat,
97                                 Standard_Byte*          theDataPtr,
98                                 const Standard_Size     theSizeX,
99                                 const Standard_Size     theSizeY,
100                                 const Standard_Size     theSizeRowBytes)
101 {
102   Clear (thePixelFormat);
103   if ((theSizeX == 0) || (theSizeY == 0) || (theDataPtr == NULL))
104   {
105     return false;
106   }
107   myData.mySizeX        = theSizeX;
108   myData.mySizeY        = theSizeY;
109   myData.mySizeRowBytes = (theSizeRowBytes != 0) ? theSizeRowBytes : (theSizeX * myData.mySizeBPP);
110   myData.myDataPtr      = theDataPtr;
111   myIsOwnPointer = false;
112   setTopDown();
113   return true;
114 }
115
116 // =======================================================================
117 // function : InitTrash
118 // purpose  :
119 // =======================================================================
120 bool Image_PixMap::InitTrash (Image_PixMap::ImgFormat thePixelFormat,
121                               const Standard_Size     theSizeX,
122                               const Standard_Size     theSizeY,
123                               const Standard_Size     theSizeRowBytes)
124 {
125   Clear (thePixelFormat);
126   if ((theSizeX == 0) || (theSizeY == 0))
127   {
128     return false;
129   }
130   myData.mySizeX        = theSizeX;
131   myData.mySizeY        = theSizeY;
132   myData.mySizeRowBytes = myData.mySizeX * myData.mySizeBPP;
133   if (theSizeRowBytes > myData.mySizeRowBytes)
134   {
135     // use argument only if it greater
136     myData.mySizeRowBytes = theSizeRowBytes;
137   }
138   myData.myDataPtr = (Standard_Byte* )Standard::AllocateAligned (SizeBytes(), 16);
139   myIsOwnPointer   = true;
140   setTopDown();
141   return myData.myDataPtr != NULL;
142 }
143
144 // =======================================================================
145 // function : InitZero
146 // purpose  :
147 // =======================================================================
148 bool Image_PixMap::InitZero (Image_PixMap::ImgFormat thePixelFormat,
149                              const Standard_Size     theSizeX,
150                              const Standard_Size     theSizeY,
151                              const Standard_Size     theSizeRowBytes,
152                              const Standard_Byte     theValue)
153 {
154   if (!InitTrash (thePixelFormat, theSizeX, theSizeY, theSizeRowBytes))
155   {
156     return false;
157   }
158   memset (myData.myDataPtr, (int )theValue, SizeBytes());
159   return true;
160 }
161
162 // =======================================================================
163 // function : InitCopy
164 // purpose  :
165 // =======================================================================
166 bool Image_PixMap::InitCopy (const Image_PixMap& theCopy)
167 {
168   if (&theCopy == this)
169   {
170     // self-copying disallowed
171     return false;
172   }
173   if (InitTrash (theCopy.myImgFormat, theCopy.myData.mySizeX, theCopy.myData.mySizeY, theCopy.myData.mySizeRowBytes))
174   {
175     memcpy (myData.myDataPtr, theCopy.myData.myDataPtr, theCopy.SizeBytes());
176     return true;
177   }
178   return false;
179 }
180
181 // =======================================================================
182 // function : Clear
183 // purpose  :
184 // =======================================================================
185 void Image_PixMap::Clear (Image_PixMap::ImgFormat thePixelFormat)
186 {
187   if (myIsOwnPointer && (myData.myDataPtr != NULL))
188   {
189     Standard::FreeAligned (myData.myDataPtr);
190   }
191   myData.myDataPtr = myData.myTopRowPtr = NULL;
192   myIsOwnPointer = true;
193   myData.mySizeX = myData.mySizeY = myData.mySizeRowBytes = 0;
194   setFormat (thePixelFormat);
195 }
196
197 // =======================================================================
198 // function : PixelColor
199 // purpose  :
200 // =======================================================================
201 Quantity_Color Image_PixMap::PixelColor (const Standard_Integer theX,
202                                          const Standard_Integer theY,
203                                          Quantity_Parameter&    theAlpha) const
204 {
205   if (IsEmpty() ||
206       theX < 0 || (Standard_Size )theX >= myData.mySizeX ||
207       theY < 0 || (Standard_Size )theY >= myData.mySizeY)
208   {
209     theAlpha = 0.0; // transparent
210     return Quantity_Color (0.0, 0.0, 0.0, Quantity_TOC_RGB);
211   }
212
213   switch (myImgFormat)
214   {
215     case ImgGrayF:
216     {
217       const Standard_ShortReal& aPixel = Value<Standard_ShortReal> (theY, theX);
218       theAlpha = 1.0; // opaque
219       return Quantity_Color (Quantity_Parameter (Standard_Real (aPixel)),
220                              Quantity_Parameter (Standard_Real (aPixel)),
221                              Quantity_Parameter (Standard_Real (aPixel)),
222                              Quantity_TOC_RGB);
223     }
224     case ImgRGBAF:
225     {
226       const Image_ColorRGBAF& aPixel = Value<Image_ColorRGBAF> (theY, theX);
227       theAlpha = aPixel.a();
228       return Quantity_Color (Quantity_Parameter (aPixel.r()),
229                              Quantity_Parameter (aPixel.g()),
230                              Quantity_Parameter (aPixel.b()),
231                              Quantity_TOC_RGB);
232     }
233     case ImgBGRAF:
234     {    
235       const Image_ColorBGRAF& aPixel = Value<Image_ColorBGRAF> (theY, theX);
236       theAlpha = aPixel.a();
237       return Quantity_Color (Quantity_Parameter (aPixel.r()),
238                              Quantity_Parameter (aPixel.g()),
239                              Quantity_Parameter (aPixel.b()),
240                              Quantity_TOC_RGB);
241     }
242     case ImgRGBF:
243     {
244       const Image_ColorRGBF& aPixel = Value<Image_ColorRGBF> (theY, theX);
245       theAlpha =  1.0; // opaque
246       return Quantity_Color (Quantity_Parameter (aPixel.r()),
247                              Quantity_Parameter (aPixel.g()),
248                              Quantity_Parameter (aPixel.b()),
249                              Quantity_TOC_RGB);
250     }
251     case ImgBGRF:
252     {
253       const Image_ColorBGRF& aPixel = Value<Image_ColorBGRF> (theY, theX);
254       theAlpha =  1.0; // opaque
255       return Quantity_Color (Quantity_Parameter (aPixel.r()),
256                              Quantity_Parameter (aPixel.g()),
257                              Quantity_Parameter (aPixel.b()),
258                              Quantity_TOC_RGB);
259     }
260     case ImgRGBA:
261     {
262       const Image_ColorRGBA& aPixel = Value<Image_ColorRGBA> (theY, theX);
263       theAlpha = Standard_Real (aPixel.a()) / 255.0;
264       return Quantity_Color (Quantity_Parameter (Standard_Real (aPixel.r()) / 255.0),
265                              Quantity_Parameter (Standard_Real (aPixel.g()) / 255.0),
266                              Quantity_Parameter (Standard_Real (aPixel.b()) / 255.0),
267                              Quantity_TOC_RGB);
268     }
269     case ImgBGRA:
270     {
271       const Image_ColorBGRA& aPixel = Value<Image_ColorBGRA> (theY, theX);
272       theAlpha = Standard_Real (aPixel.a()) / 255.0;
273       return Quantity_Color (Quantity_Parameter (Standard_Real (aPixel.r()) / 255.0),
274                              Quantity_Parameter (Standard_Real (aPixel.g()) / 255.0),
275                              Quantity_Parameter (Standard_Real (aPixel.b()) / 255.0),
276                              Quantity_TOC_RGB);
277     }
278     case ImgRGB32:
279     {
280       const Image_ColorRGB32& aPixel = Value<Image_ColorRGB32> (theY, theX);
281       theAlpha = 1.0; // opaque
282       return Quantity_Color (Quantity_Parameter (Standard_Real (aPixel.r()) / 255.0),
283                              Quantity_Parameter (Standard_Real (aPixel.g()) / 255.0),
284                              Quantity_Parameter (Standard_Real (aPixel.b()) / 255.0),
285                              Quantity_TOC_RGB);
286     }
287     case ImgBGR32:
288     {
289       const Image_ColorBGR32& aPixel = Value<Image_ColorBGR32> (theY, theX);
290       theAlpha = 1.0; // opaque
291       return Quantity_Color (Quantity_Parameter (Standard_Real (aPixel.r()) / 255.0),
292                              Quantity_Parameter (Standard_Real (aPixel.g()) / 255.0),
293                              Quantity_Parameter (Standard_Real (aPixel.b()) / 255.0),
294                              Quantity_TOC_RGB);
295     }
296     case ImgRGB:
297     {
298       const Image_ColorRGB& aPixel = Value<Image_ColorRGB> (theY, theX);
299       theAlpha = 1.0; // opaque
300       return Quantity_Color (Quantity_Parameter (Standard_Real (aPixel.r()) / 255.0),
301                              Quantity_Parameter (Standard_Real (aPixel.g()) / 255.0),
302                              Quantity_Parameter (Standard_Real (aPixel.b()) / 255.0),
303                              Quantity_TOC_RGB);
304     }
305     case ImgBGR:
306     {
307       const Image_ColorBGR& aPixel = Value<Image_ColorBGR> (theY, theX);
308       theAlpha = 1.0; // opaque
309       return Quantity_Color (Quantity_Parameter (Standard_Real (aPixel.r()) / 255.0),
310                              Quantity_Parameter (Standard_Real (aPixel.g()) / 255.0),
311                              Quantity_Parameter (Standard_Real (aPixel.b()) / 255.0),
312                              Quantity_TOC_RGB);
313     }
314     case ImgGray:
315     {
316       const Standard_Byte& aPixel = Value<Standard_Byte> (theY, theX);
317       theAlpha = 1.0; // opaque
318       return Quantity_Color (Quantity_Parameter (Standard_Real (aPixel) / 255.0),
319                              Quantity_Parameter (Standard_Real (aPixel) / 255.0),
320                              Quantity_Parameter (Standard_Real (aPixel) / 255.0),
321                              Quantity_TOC_RGB);
322     }
323     default:
324     {
325       // not supported image type
326       theAlpha = 0.0; // transparent
327       return Quantity_Color (0.0, 0.0, 0.0, Quantity_TOC_RGB);
328     }
329   }
330 }