0024534: Improve design of Image_PixMap class
[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 <NCollection_AlignedAllocator.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 {
29   //
30 }
31
32 // =======================================================================
33 // function : ~Image_PixMap
34 // purpose  :
35 // =======================================================================
36 Image_PixMap::~Image_PixMap()
37 {
38   Clear();
39 }
40
41 Standard_Size Image_PixMap::SizePixelBytes (const Image_PixMap::ImgFormat thePixelFormat)
42 {
43   switch (thePixelFormat)
44   {
45     case ImgGrayF:
46       return sizeof(float);
47     case ImgRGBAF:
48     case ImgBGRAF:
49       return sizeof(float) * 4;
50     case ImgRGBF:
51     case ImgBGRF:
52       return sizeof(float) * 3;
53     case ImgRGBA:
54     case ImgBGRA:
55       return 4;
56     case ImgRGB32:
57     case ImgBGR32:
58       return 4;
59     case ImgRGB:
60     case ImgBGR:
61       return 3;
62     case ImgGray:
63     default:
64       return 1;
65   }
66 }
67
68 // =======================================================================
69 // function : setFormat
70 // purpose  :
71 // =======================================================================
72 void Image_PixMap::setFormat (Image_PixMap::ImgFormat thePixelFormat)
73 {
74   myImgFormat = thePixelFormat;
75 }
76
77 // =======================================================================
78 // function : InitWrapper
79 // purpose  :
80 // =======================================================================
81 bool Image_PixMap::InitWrapper (Image_PixMap::ImgFormat thePixelFormat,
82                                 Standard_Byte*          theDataPtr,
83                                 const Standard_Size     theSizeX,
84                                 const Standard_Size     theSizeY,
85                                 const Standard_Size     theSizeRowBytes)
86 {
87   Clear();
88   myImgFormat = thePixelFormat;
89   if ((theSizeX == 0) || (theSizeY == 0) || (theDataPtr == NULL))
90   {
91     return false;
92   }
93
94   Handle(NCollection_BaseAllocator) anEmptyAlloc;
95   myData.Init (anEmptyAlloc, Image_PixMap::SizePixelBytes (thePixelFormat),
96                theSizeX, theSizeY, theSizeRowBytes, theDataPtr);
97   return true;
98 }
99
100 // =======================================================================
101 // function : InitTrash
102 // purpose  :
103 // =======================================================================
104 bool Image_PixMap::InitTrash (Image_PixMap::ImgFormat thePixelFormat,
105                               const Standard_Size     theSizeX,
106                               const Standard_Size     theSizeY,
107                               const Standard_Size     theSizeRowBytes)
108 {
109   Clear();
110   myImgFormat = thePixelFormat;
111   if ((theSizeX == 0) || (theSizeY == 0))
112   {
113     return false;
114   }
115
116   // use argument only if it greater
117   const Standard_Size aSizeRowBytes = std::max (theSizeRowBytes, theSizeX * SizePixelBytes (thePixelFormat));
118   Handle(NCollection_BaseAllocator) anAlloc = new NCollection_AlignedAllocator (16);
119   myData.Init (anAlloc, Image_PixMap::SizePixelBytes (thePixelFormat),
120                theSizeX, theSizeY, aSizeRowBytes, NULL);
121   return !myData.IsEmpty();
122 }
123
124 // =======================================================================
125 // function : InitZero
126 // purpose  :
127 // =======================================================================
128 bool Image_PixMap::InitZero (Image_PixMap::ImgFormat thePixelFormat,
129                              const Standard_Size     theSizeX,
130                              const Standard_Size     theSizeY,
131                              const Standard_Size     theSizeRowBytes,
132                              const Standard_Byte     theValue)
133 {
134   if (!InitTrash (thePixelFormat, theSizeX, theSizeY, theSizeRowBytes))
135   {
136     return false;
137   }
138   memset (myData.ChangeData(), (int )theValue, SizeBytes());
139   return true;
140 }
141
142 // =======================================================================
143 // function : InitCopy
144 // purpose  :
145 // =======================================================================
146 bool Image_PixMap::InitCopy (const Image_PixMap& theCopy)
147 {
148   if (&theCopy == this)
149   {
150     // self-copying disallowed
151     return false;
152   }
153   if (InitTrash (theCopy.myImgFormat, theCopy.SizeX(), theCopy.SizeY(), theCopy.SizeRowBytes()))
154   {
155     memcpy (myData.ChangeData(), theCopy.myData.Data(), theCopy.SizeBytes());
156     return true;
157   }
158   return false;
159 }
160
161 // =======================================================================
162 // function : Clear
163 // purpose  :
164 // =======================================================================
165 void Image_PixMap::Clear()
166 {
167   Handle(NCollection_BaseAllocator) anEmptyAlloc;
168   myData.Init (anEmptyAlloc, Image_PixMap::SizePixelBytes (myImgFormat),
169                0, 0, 0, NULL);
170 }
171
172 // =======================================================================
173 // function : PixelColor
174 // purpose  :
175 // =======================================================================
176 Quantity_Color Image_PixMap::PixelColor (const Standard_Integer theX,
177                                          const Standard_Integer theY,
178                                          Quantity_Parameter&    theAlpha) const
179 {
180   if (IsEmpty()
181    || theX < 0 || (Standard_Size )theX >= SizeX()
182    || theY < 0 || (Standard_Size )theY >= SizeY())
183   {
184     theAlpha = 0.0; // transparent
185     return Quantity_Color (0.0, 0.0, 0.0, Quantity_TOC_RGB);
186   }
187
188   switch (myImgFormat)
189   {
190     case ImgGrayF:
191     {
192       const Standard_ShortReal& aPixel = Value<Standard_ShortReal> (theY, theX);
193       theAlpha = 1.0; // opaque
194       return Quantity_Color (Quantity_Parameter (Standard_Real (aPixel)),
195                              Quantity_Parameter (Standard_Real (aPixel)),
196                              Quantity_Parameter (Standard_Real (aPixel)),
197                              Quantity_TOC_RGB);
198     }
199     case ImgRGBAF:
200     {
201       const Image_ColorRGBAF& aPixel = Value<Image_ColorRGBAF> (theY, theX);
202       theAlpha = aPixel.a();
203       return Quantity_Color (Quantity_Parameter (aPixel.r()),
204                              Quantity_Parameter (aPixel.g()),
205                              Quantity_Parameter (aPixel.b()),
206                              Quantity_TOC_RGB);
207     }
208     case ImgBGRAF:
209     {    
210       const Image_ColorBGRAF& aPixel = Value<Image_ColorBGRAF> (theY, theX);
211       theAlpha = aPixel.a();
212       return Quantity_Color (Quantity_Parameter (aPixel.r()),
213                              Quantity_Parameter (aPixel.g()),
214                              Quantity_Parameter (aPixel.b()),
215                              Quantity_TOC_RGB);
216     }
217     case ImgRGBF:
218     {
219       const Image_ColorRGBF& aPixel = Value<Image_ColorRGBF> (theY, theX);
220       theAlpha =  1.0; // opaque
221       return Quantity_Color (Quantity_Parameter (aPixel.r()),
222                              Quantity_Parameter (aPixel.g()),
223                              Quantity_Parameter (aPixel.b()),
224                              Quantity_TOC_RGB);
225     }
226     case ImgBGRF:
227     {
228       const Image_ColorBGRF& aPixel = Value<Image_ColorBGRF> (theY, theX);
229       theAlpha =  1.0; // opaque
230       return Quantity_Color (Quantity_Parameter (aPixel.r()),
231                              Quantity_Parameter (aPixel.g()),
232                              Quantity_Parameter (aPixel.b()),
233                              Quantity_TOC_RGB);
234     }
235     case ImgRGBA:
236     {
237       const Image_ColorRGBA& aPixel = Value<Image_ColorRGBA> (theY, theX);
238       theAlpha = Standard_Real (aPixel.a()) / 255.0;
239       return Quantity_Color (Quantity_Parameter (Standard_Real (aPixel.r()) / 255.0),
240                              Quantity_Parameter (Standard_Real (aPixel.g()) / 255.0),
241                              Quantity_Parameter (Standard_Real (aPixel.b()) / 255.0),
242                              Quantity_TOC_RGB);
243     }
244     case ImgBGRA:
245     {
246       const Image_ColorBGRA& aPixel = Value<Image_ColorBGRA> (theY, theX);
247       theAlpha = Standard_Real (aPixel.a()) / 255.0;
248       return Quantity_Color (Quantity_Parameter (Standard_Real (aPixel.r()) / 255.0),
249                              Quantity_Parameter (Standard_Real (aPixel.g()) / 255.0),
250                              Quantity_Parameter (Standard_Real (aPixel.b()) / 255.0),
251                              Quantity_TOC_RGB);
252     }
253     case ImgRGB32:
254     {
255       const Image_ColorRGB32& aPixel = Value<Image_ColorRGB32> (theY, theX);
256       theAlpha = 1.0; // opaque
257       return Quantity_Color (Quantity_Parameter (Standard_Real (aPixel.r()) / 255.0),
258                              Quantity_Parameter (Standard_Real (aPixel.g()) / 255.0),
259                              Quantity_Parameter (Standard_Real (aPixel.b()) / 255.0),
260                              Quantity_TOC_RGB);
261     }
262     case ImgBGR32:
263     {
264       const Image_ColorBGR32& aPixel = Value<Image_ColorBGR32> (theY, theX);
265       theAlpha = 1.0; // opaque
266       return Quantity_Color (Quantity_Parameter (Standard_Real (aPixel.r()) / 255.0),
267                              Quantity_Parameter (Standard_Real (aPixel.g()) / 255.0),
268                              Quantity_Parameter (Standard_Real (aPixel.b()) / 255.0),
269                              Quantity_TOC_RGB);
270     }
271     case ImgRGB:
272     {
273       const Image_ColorRGB& aPixel = Value<Image_ColorRGB> (theY, theX);
274       theAlpha = 1.0; // opaque
275       return Quantity_Color (Quantity_Parameter (Standard_Real (aPixel.r()) / 255.0),
276                              Quantity_Parameter (Standard_Real (aPixel.g()) / 255.0),
277                              Quantity_Parameter (Standard_Real (aPixel.b()) / 255.0),
278                              Quantity_TOC_RGB);
279     }
280     case ImgBGR:
281     {
282       const Image_ColorBGR& aPixel = Value<Image_ColorBGR> (theY, theX);
283       theAlpha = 1.0; // opaque
284       return Quantity_Color (Quantity_Parameter (Standard_Real (aPixel.r()) / 255.0),
285                              Quantity_Parameter (Standard_Real (aPixel.g()) / 255.0),
286                              Quantity_Parameter (Standard_Real (aPixel.b()) / 255.0),
287                              Quantity_TOC_RGB);
288     }
289     case ImgGray:
290     {
291       const Standard_Byte& aPixel = Value<Standard_Byte> (theY, theX);
292       theAlpha = 1.0; // opaque
293       return Quantity_Color (Quantity_Parameter (Standard_Real (aPixel) / 255.0),
294                              Quantity_Parameter (Standard_Real (aPixel) / 255.0),
295                              Quantity_Parameter (Standard_Real (aPixel) / 255.0),
296                              Quantity_TOC_RGB);
297     }
298     default:
299     {
300       // not supported image type
301       theAlpha = 0.0; // transparent
302       return Quantity_Color (0.0, 0.0, 0.0, Quantity_TOC_RGB);
303     }
304   }
305 }