ffbac02a70f364a2ad717d8e1d5f935d7db1897d
[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 #include <Standard_ProgramError.hxx>
19
20 #include <algorithm>
21
22 IMPLEMENT_STANDARD_RTTIEXT(Image_PixMap,Standard_Transient)
23
24 // =======================================================================
25 // function : Image_PixMap
26 // purpose  :
27 // =======================================================================
28 Image_PixMap::Image_PixMap()
29 : myImgFormat (Image_Format_Gray)
30 {
31   //
32 }
33
34 // =======================================================================
35 // function : ~Image_PixMap
36 // purpose  :
37 // =======================================================================
38 Image_PixMap::~Image_PixMap()
39 {
40   Clear();
41 }
42
43 Standard_Size Image_PixMap::SizePixelBytes (const Image_Format thePixelFormat)
44 {
45   switch (thePixelFormat)
46   {
47     case Image_Format_GrayF:
48     case Image_Format_AlphaF:
49       return sizeof(float);
50     case Image_Format_RGBAF:
51     case Image_Format_BGRAF:
52       return sizeof(float) * 4;
53     case Image_Format_RGBF:
54     case Image_Format_BGRF:
55       return sizeof(float) * 3;
56     case Image_Format_RGBA:
57     case Image_Format_BGRA:
58       return 4;
59     case Image_Format_RGB32:
60     case Image_Format_BGR32:
61       return 4;
62     case Image_Format_RGB:
63     case Image_Format_BGR:
64       return 3;
65     case Image_Format_Gray:
66     case Image_Format_Alpha:
67       return 1;
68     case Image_Format_UNKNOWN:
69       return 1;
70   }
71   return 1;
72 }
73
74 // =======================================================================
75 // function : SetFormat
76 // purpose  :
77 // =======================================================================
78 void Image_PixMap::SetFormat (Image_Format thePixelFormat)
79 {
80   if (myImgFormat == thePixelFormat)
81   {
82     return;
83   }
84
85   if (!IsEmpty()
86     && SizePixelBytes (myImgFormat) != SizePixelBytes (thePixelFormat))
87   {
88     throw Standard_ProgramError("Image_PixMap::SetFormat() - incompatible pixel format");
89     return;
90   }
91
92   myImgFormat = thePixelFormat;
93 }
94
95 // =======================================================================
96 // function : InitWrapper
97 // purpose  :
98 // =======================================================================
99 bool Image_PixMap::InitWrapper (Image_Format        thePixelFormat,
100                                 Standard_Byte*      theDataPtr,
101                                 const Standard_Size theSizeX,
102                                 const Standard_Size theSizeY,
103                                 const Standard_Size theSizeRowBytes)
104 {
105   Clear();
106   myImgFormat = thePixelFormat;
107   if ((theSizeX == 0) || (theSizeY == 0) || (theDataPtr == NULL))
108   {
109     return false;
110   }
111
112   Handle(NCollection_BaseAllocator) anEmptyAlloc;
113   myData.Init (anEmptyAlloc, Image_PixMap::SizePixelBytes (thePixelFormat),
114                theSizeX, theSizeY, theSizeRowBytes, theDataPtr);
115   return true;
116 }
117
118 // =======================================================================
119 // function : InitTrash
120 // purpose  :
121 // =======================================================================
122 bool Image_PixMap::InitTrash (Image_Format        thePixelFormat,
123                               const Standard_Size theSizeX,
124                               const Standard_Size theSizeY,
125                               const Standard_Size theSizeRowBytes)
126 {
127   Clear();
128   myImgFormat = thePixelFormat;
129   if ((theSizeX == 0) || (theSizeY == 0))
130   {
131     return false;
132   }
133
134   // use argument only if it greater
135   const Standard_Size aSizeRowBytes = std::max (theSizeRowBytes, theSizeX * SizePixelBytes (thePixelFormat));
136   Handle(NCollection_BaseAllocator) anAlloc = new NCollection_AlignedAllocator (16);
137   myData.Init (anAlloc, Image_PixMap::SizePixelBytes (thePixelFormat),
138                theSizeX, theSizeY, aSizeRowBytes, NULL);
139   return !myData.IsEmpty();
140 }
141
142 // =======================================================================
143 // function : InitZero
144 // purpose  :
145 // =======================================================================
146 bool Image_PixMap::InitZero (Image_Format        thePixelFormat,
147                              const Standard_Size theSizeX,
148                              const Standard_Size theSizeY,
149                              const Standard_Size theSizeRowBytes,
150                              const Standard_Byte theValue)
151 {
152   if (!InitTrash (thePixelFormat, theSizeX, theSizeY, theSizeRowBytes))
153   {
154     return false;
155   }
156   memset (myData.ChangeData(), (int )theValue, SizeBytes());
157   return true;
158 }
159
160 // =======================================================================
161 // function : InitCopy
162 // purpose  :
163 // =======================================================================
164 bool Image_PixMap::InitCopy (const Image_PixMap& theCopy)
165 {
166   if (&theCopy == this)
167   {
168     // self-copying disallowed
169     return false;
170   }
171   if (InitTrash (theCopy.myImgFormat, theCopy.SizeX(), theCopy.SizeY(), theCopy.SizeRowBytes()))
172   {
173     memcpy (myData.ChangeData(), theCopy.myData.Data(), theCopy.SizeBytes());
174     return true;
175   }
176   return false;
177 }
178
179 // =======================================================================
180 // function : Clear
181 // purpose  :
182 // =======================================================================
183 void Image_PixMap::Clear()
184 {
185   Handle(NCollection_BaseAllocator) anEmptyAlloc;
186   myData.Init (anEmptyAlloc, Image_PixMap::SizePixelBytes (myImgFormat),
187                0, 0, 0, NULL);
188 }
189
190 // =======================================================================
191 // function : PixelColor
192 // purpose  :
193 // =======================================================================
194 Quantity_ColorRGBA Image_PixMap::PixelColor (const Standard_Integer theX,
195                                              const Standard_Integer theY,
196                                              const Standard_Boolean theToLinearize) const
197 {
198   if (IsEmpty()
199    || theX < 0 || (Standard_Size )theX >= SizeX()
200    || theY < 0 || (Standard_Size )theY >= SizeY())
201   {
202     return Quantity_ColorRGBA (0.0f, 0.0f, 0.0f, 0.0f); // transparent
203   }
204
205   switch (myImgFormat)
206   {
207     case Image_Format_GrayF:
208     {
209       const Standard_ShortReal& aPixel = Value<Standard_ShortReal> (theY, theX);
210       return Quantity_ColorRGBA (NCollection_Vec4<float> (aPixel, aPixel, aPixel, 1.0f)); // opaque
211     }
212     case Image_Format_AlphaF:
213     {
214       const Standard_ShortReal& aPixel = Value<Standard_ShortReal> (theY, theX);
215       return Quantity_ColorRGBA (NCollection_Vec4<float> (1.0f, 1.0f, 1.0f, aPixel));
216     }
217     case Image_Format_RGBAF:
218     {
219       const Image_ColorRGBAF& aPixel = Value<Image_ColorRGBAF> (theY, theX);
220       return Quantity_ColorRGBA (NCollection_Vec4<float> (aPixel.r(), aPixel.g(), aPixel.b(), aPixel.a()));
221     }
222     case Image_Format_BGRAF:
223     {    
224       const Image_ColorBGRAF& aPixel = Value<Image_ColorBGRAF> (theY, theX);
225       return Quantity_ColorRGBA (NCollection_Vec4<float> (aPixel.r(), aPixel.g(), aPixel.b(), aPixel.a()));
226     }
227     case Image_Format_RGBF:
228     {
229       const Image_ColorRGBF& aPixel = Value<Image_ColorRGBF> (theY, theX);
230       return Quantity_ColorRGBA (NCollection_Vec4<float> (aPixel.r(), aPixel.g(), aPixel.b(), 1.0f)); // opaque
231     }
232     case Image_Format_BGRF:
233     {
234       const Image_ColorBGRF& aPixel = Value<Image_ColorBGRF> (theY, theX);
235       return Quantity_ColorRGBA (NCollection_Vec4<float> (aPixel.r(), aPixel.g(), aPixel.b(), 1.0f)); // opaque
236     }
237     case Image_Format_RGBA:
238     {
239       const Image_ColorRGBA& aPixel = Value<Image_ColorRGBA> (theY, theX);
240       return theToLinearize
241            ? Quantity_ColorRGBA (Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.r()) / 255.0f),
242                                  Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.g()) / 255.0f),
243                                  Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.b()) / 255.0f),
244                                  float(aPixel.a()) / 255.0f)
245            : Quantity_ColorRGBA (float(aPixel.r()) / 255.0f, float(aPixel.g()) / 255.0f, float(aPixel.b()) / 255.0f, float(aPixel.a()) / 255.0f);
246     }
247     case Image_Format_BGRA:
248     {
249       const Image_ColorBGRA& aPixel = Value<Image_ColorBGRA> (theY, theX);
250       return theToLinearize
251            ? Quantity_ColorRGBA (Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.r()) / 255.0f),
252                                  Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.g()) / 255.0f),
253                                  Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.b()) / 255.0f),
254                                  float(aPixel.a()) / 255.0f)
255            : Quantity_ColorRGBA (float(aPixel.r()) / 255.0f, float(aPixel.g()) / 255.0f, float(aPixel.b()) / 255.0f, float(aPixel.a()) / 255.0f);
256     }
257     case Image_Format_RGB32:
258     {
259       const Image_ColorRGB32& aPixel = Value<Image_ColorRGB32> (theY, theX);
260       return theToLinearize
261            ? Quantity_ColorRGBA (Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.r()) / 255.0f),
262                                  Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.g()) / 255.0f),
263                                  Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.b()) / 255.0f), 1.0f)
264            : Quantity_ColorRGBA (float(aPixel.r()) / 255.0f, float(aPixel.g()) / 255.0f, float(aPixel.b()) / 255.0f, 1.0f);
265     }
266     case Image_Format_BGR32:
267     {
268       const Image_ColorBGR32& aPixel = Value<Image_ColorBGR32> (theY, theX);
269       return theToLinearize
270            ? Quantity_ColorRGBA (Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.r()) / 255.0f),
271                                  Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.g()) / 255.0f),
272                                  Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.b()) / 255.0f), 1.0f)
273            : Quantity_ColorRGBA (float(aPixel.r()) / 255.0f, float(aPixel.g()) / 255.0f, float(aPixel.b()) / 255.0f, 1.0f);
274     }
275     case Image_Format_RGB:
276     {
277       const Image_ColorRGB& aPixel = Value<Image_ColorRGB> (theY, theX);
278       return theToLinearize
279            ? Quantity_ColorRGBA (Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.r()) / 255.0f),
280                                  Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.g()) / 255.0f),
281                                  Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.b()) / 255.0f), 1.0f)
282            : Quantity_ColorRGBA (float(aPixel.r()) / 255.0f, float(aPixel.g()) / 255.0f, float(aPixel.b()) / 255.0f, 1.0f);
283     }
284     case Image_Format_BGR:
285     {
286       const Image_ColorBGR& aPixel = Value<Image_ColorBGR> (theY, theX);
287       return theToLinearize
288            ? Quantity_ColorRGBA (Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.r()) / 255.0f),
289                                  Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.g()) / 255.0f),
290                                  Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.b()) / 255.0f), 1.0f)
291            : Quantity_ColorRGBA (float(aPixel.r()) / 255.0f, float(aPixel.g()) / 255.0f, float(aPixel.b()) / 255.0f, 1.0f);
292     }
293     case Image_Format_Gray:
294     {
295       const Standard_Byte& aPixel = Value<Standard_Byte> (theY, theX);
296       return Quantity_ColorRGBA (float(aPixel) / 255.0f, float(aPixel) / 255.0f, float(aPixel) / 255.0f, 1.0f); // opaque
297     }
298     case Image_Format_Alpha:
299     {
300       const Standard_Byte& aPixel = Value<Standard_Byte> (theY, theX);
301       return Quantity_ColorRGBA (1.0f, 1.0f, 1.0f, float(aPixel) / 255.0f);
302     }
303     case Image_Format_UNKNOWN:
304     {
305       break;
306     }
307   }
308
309   // unsupported image type
310   return Quantity_ColorRGBA (0.0f, 0.0f, 0.0f, 0.0f); // transparent
311 }
312
313 // =======================================================================
314 // function : SetPixelColor
315 // purpose  :
316 // =======================================================================
317 void Image_PixMap::SetPixelColor (const Standard_Integer theX,
318                                   const Standard_Integer theY,
319                                   const Quantity_ColorRGBA& theColor,
320                                   const Standard_Boolean theToDeLinearize)
321 {
322   if (IsEmpty()
323    || theX < 0 || Standard_Size(theX) >= SizeX()
324    || theY < 0 || Standard_Size(theY) >= SizeY())
325   {
326     return;
327   }
328
329   const NCollection_Vec4<float>& aColor = theColor;
330   switch (myImgFormat)
331   {
332     case Image_Format_GrayF:
333     {
334       ChangeValue<Standard_ShortReal> (theY, theX) = aColor.r();
335       return;
336     }
337     case Image_Format_AlphaF:
338     {
339       ChangeValue<Standard_ShortReal> (theY, theX) = aColor.a();
340       return;
341     }
342     case Image_Format_RGBAF:
343     {
344       Image_ColorRGBAF& aPixel = ChangeValue<Image_ColorRGBAF> (theY, theX);
345       aPixel.r() = aColor.r();
346       aPixel.g() = aColor.g();
347       aPixel.b() = aColor.b();
348       aPixel.a() = aColor.a();
349       return;
350     }
351     case Image_Format_BGRAF:
352     {
353       Image_ColorBGRAF& aPixel = ChangeValue<Image_ColorBGRAF> (theY, theX);
354       aPixel.r() = aColor.r();
355       aPixel.g() = aColor.g();
356       aPixel.b() = aColor.b();
357       aPixel.a() = aColor.a();
358       return;
359     }
360     case Image_Format_RGBF:
361     {
362       Image_ColorRGBF& aPixel = ChangeValue<Image_ColorRGBF> (theY, theX);
363       aPixel.r() = aColor.r();
364       aPixel.g() = aColor.g();
365       aPixel.b() = aColor.b();
366       return;
367     }
368     case Image_Format_BGRF:
369     {
370       Image_ColorBGRF& aPixel = ChangeValue<Image_ColorBGRF> (theY, theX);
371       aPixel.r() = aColor.r();
372       aPixel.g() = aColor.g();
373       aPixel.b() = aColor.b();
374       return;
375     }
376     case Image_Format_RGBA:
377     {
378       Image_ColorRGBA& aPixel = ChangeValue<Image_ColorRGBA> (theY, theX);
379       if (theToDeLinearize)
380       {
381         aPixel.r() = Standard_Byte(Quantity_Color::Convert_LinearRGB_To_sRGB (aColor.r()) * 255.0f);
382         aPixel.g() = Standard_Byte(Quantity_Color::Convert_LinearRGB_To_sRGB (aColor.g()) * 255.0f);
383         aPixel.b() = Standard_Byte(Quantity_Color::Convert_LinearRGB_To_sRGB (aColor.b()) * 255.0f);
384       }
385       else
386       {
387         aPixel.r() = Standard_Byte(aColor.r() * 255.0f);
388         aPixel.g() = Standard_Byte(aColor.g() * 255.0f);
389         aPixel.b() = Standard_Byte(aColor.b() * 255.0f);
390       }
391       aPixel.a() = Standard_Byte(aColor.a() * 255.0f);
392       return;
393     }
394     case Image_Format_BGRA:
395     {
396       Image_ColorBGRA& aPixel = ChangeValue<Image_ColorBGRA> (theY, theX);
397       if (theToDeLinearize)
398       {
399         aPixel.r() = Standard_Byte(Quantity_Color::Convert_LinearRGB_To_sRGB (aColor.r()) * 255.0f);
400         aPixel.g() = Standard_Byte(Quantity_Color::Convert_LinearRGB_To_sRGB (aColor.g()) * 255.0f);
401         aPixel.b() = Standard_Byte(Quantity_Color::Convert_LinearRGB_To_sRGB (aColor.b()) * 255.0f);
402       }
403       else
404       {
405         aPixel.r() = Standard_Byte(aColor.r() * 255.0f);
406         aPixel.g() = Standard_Byte(aColor.g() * 255.0f);
407         aPixel.b() = Standard_Byte(aColor.b() * 255.0f);
408       }
409       aPixel.a() = Standard_Byte(aColor.a() * 255.0f);
410       return;
411     }
412     case Image_Format_RGB32:
413     {
414       Image_ColorRGB32& aPixel = ChangeValue<Image_ColorRGB32> (theY, theX);
415       if (theToDeLinearize)
416       {
417         aPixel.r()  = Standard_Byte(Quantity_Color::Convert_LinearRGB_To_sRGB (aColor.r()) * 255.0f);
418         aPixel.g()  = Standard_Byte(Quantity_Color::Convert_LinearRGB_To_sRGB (aColor.g()) * 255.0f);
419         aPixel.b()  = Standard_Byte(Quantity_Color::Convert_LinearRGB_To_sRGB (aColor.b()) * 255.0f);
420       }
421       else
422       {
423         aPixel.r()  = Standard_Byte(aColor.r() * 255.0f);
424         aPixel.g()  = Standard_Byte(aColor.g() * 255.0f);
425         aPixel.b()  = Standard_Byte(aColor.b() * 255.0f);
426       }
427       aPixel.a_() = 255;
428       return;
429     }
430     case Image_Format_BGR32:
431     {
432       Image_ColorBGR32& aPixel = ChangeValue<Image_ColorBGR32> (theY, theX);
433       if (theToDeLinearize)
434       {
435         aPixel.r()  = Standard_Byte(Quantity_Color::Convert_LinearRGB_To_sRGB (aColor.r()) * 255.0f);
436         aPixel.g()  = Standard_Byte(Quantity_Color::Convert_LinearRGB_To_sRGB (aColor.g()) * 255.0f);
437         aPixel.b()  = Standard_Byte(Quantity_Color::Convert_LinearRGB_To_sRGB (aColor.b()) * 255.0f);
438       }
439       else
440       {
441         aPixel.r()  = Standard_Byte(aColor.r() * 255.0f);
442         aPixel.g()  = Standard_Byte(aColor.g() * 255.0f);
443         aPixel.b()  = Standard_Byte(aColor.b() * 255.0f);
444       }
445       aPixel.a_() = 255;
446       return;
447     }
448     case Image_Format_RGB:
449     {
450       Image_ColorRGB& aPixel = ChangeValue<Image_ColorRGB> (theY, theX);
451       if (theToDeLinearize)
452       {
453         aPixel.r() = Standard_Byte(Quantity_Color::Convert_LinearRGB_To_sRGB (aColor.r()) * 255.0f);
454         aPixel.g() = Standard_Byte(Quantity_Color::Convert_LinearRGB_To_sRGB (aColor.g()) * 255.0f);
455         aPixel.b() = Standard_Byte(Quantity_Color::Convert_LinearRGB_To_sRGB (aColor.b()) * 255.0f);
456       }
457       else
458       {
459         aPixel.r() = Standard_Byte(aColor.r() * 255.0f);
460         aPixel.g() = Standard_Byte(aColor.g() * 255.0f);
461         aPixel.b() = Standard_Byte(aColor.b() * 255.0f);
462       }
463       return;
464     }
465     case Image_Format_BGR:
466     {
467       Image_ColorBGR& aPixel = ChangeValue<Image_ColorBGR> (theY, theX);
468       if (theToDeLinearize)
469       {
470         aPixel.r() = Standard_Byte(Quantity_Color::Convert_LinearRGB_To_sRGB (aColor.r()) * 255.0f);
471         aPixel.g() = Standard_Byte(Quantity_Color::Convert_LinearRGB_To_sRGB (aColor.g()) * 255.0f);
472         aPixel.b() = Standard_Byte(Quantity_Color::Convert_LinearRGB_To_sRGB (aColor.b()) * 255.0f);
473       }
474       else
475       {
476         aPixel.r() = Standard_Byte(aColor.r() * 255.0f);
477         aPixel.g() = Standard_Byte(aColor.g() * 255.0f);
478         aPixel.b() = Standard_Byte(aColor.b() * 255.0f);
479       }
480       return;
481     }
482     case Image_Format_Gray:
483     {
484       ChangeValue<Standard_Byte> (theY, theX) = Standard_Byte(aColor.r() * 255.0f);
485       return;
486     }
487     case Image_Format_Alpha:
488     {
489       ChangeValue<Standard_Byte> (theY, theX) = Standard_Byte(aColor.a() * 255.0f);
490       return;
491     }
492     case Image_Format_UNKNOWN:
493     {
494       return;
495     }
496   }
497 }
498
499 // =======================================================================
500 // function : SwapRgbaBgra
501 // purpose  :
502 // =======================================================================
503 bool Image_PixMap::SwapRgbaBgra (Image_PixMap& theImage)
504 {
505   switch (theImage.Format())
506   {
507     case Image_Format_BGR32:
508     case Image_Format_RGB32:
509     case Image_Format_BGRA:
510     case Image_Format_RGBA:
511     {
512       const bool toResetAlpha = theImage.Format() == Image_Format_BGR32
513                              || theImage.Format() == Image_Format_RGB32;
514       for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
515       {
516         for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol)
517         {
518           Image_ColorRGBA& aPixel     = theImage.ChangeValue<Image_ColorRGBA> (aRow, aCol);
519           Image_ColorBGRA  aPixelCopy = theImage.Value      <Image_ColorBGRA> (aRow, aCol);
520           aPixel.r() = aPixelCopy.r();
521           aPixel.g() = aPixelCopy.g();
522           aPixel.b() = aPixelCopy.b();
523           if (toResetAlpha)
524           {
525             aPixel.a() = 255;
526           }
527         }
528       }
529       return true;
530     }
531     case Image_Format_BGR:
532     case Image_Format_RGB:
533     {
534       for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
535       {
536         for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol)
537         {
538           Image_ColorRGB& aPixel     = theImage.ChangeValue<Image_ColorRGB> (aRow, aCol);
539           Image_ColorBGR  aPixelCopy = theImage.Value      <Image_ColorBGR> (aRow, aCol);
540           aPixel.r() = aPixelCopy.r();
541           aPixel.g() = aPixelCopy.g();
542           aPixel.b() = aPixelCopy.b();
543         }
544       }
545       return true;
546     }
547     case Image_Format_BGRF:
548     case Image_Format_RGBF:
549     case Image_Format_BGRAF:
550     case Image_Format_RGBAF:
551     {
552       for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
553       {
554         for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol)
555         {
556           Image_ColorRGBF& aPixel     = theImage.ChangeValue<Image_ColorRGBF> (aRow, aCol);
557           Image_ColorBGRF  aPixelCopy = theImage.Value      <Image_ColorBGRF> (aRow, aCol);
558           aPixel.r() = aPixelCopy.r();
559           aPixel.g() = aPixelCopy.g();
560           aPixel.b() = aPixelCopy.b();
561         }
562       }
563       return true;
564     }
565     default: return false;
566   }
567 }
568
569 // =======================================================================
570 // function : ToBlackWhite
571 // purpose  :
572 // =======================================================================
573 void Image_PixMap::ToBlackWhite (Image_PixMap& theImage)
574 {
575   switch (theImage.Format())
576   {
577     case Image_Format_Gray:
578     case Image_Format_Alpha:
579     {
580       for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
581       {
582         for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol)
583         {
584           unsigned char& aPixel = theImage.ChangeValue<unsigned char> (aRow, aCol);
585           if (aPixel != 0)
586           {
587             aPixel = 255;
588           }
589         }
590       }
591       break;
592     }
593     case Image_Format_RGB:
594     case Image_Format_BGR:
595     case Image_Format_RGB32:
596     case Image_Format_BGR32:
597     case Image_Format_RGBA:
598     case Image_Format_BGRA:
599     {
600       const NCollection_Vec3<unsigned char> aWhite24 (255, 255, 255);
601       for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
602       {
603         for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol)
604         {
605           NCollection_Vec3<unsigned char>& aPixel = theImage.ChangeValue< NCollection_Vec3<unsigned char> > (aRow, aCol);
606           if (aPixel[0] != 0
607            || aPixel[1] != 0
608            || aPixel[2] != 0)
609           {
610             aPixel = aWhite24;
611           }
612         }
613       }
614       break;
615     }
616     default:
617     {
618       const Quantity_ColorRGBA aWhiteRgba (1.0f, 1.0f, 1.0f, 1.0f);
619       for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
620       {
621         for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol)
622         {
623           const Quantity_ColorRGBA       aPixelRgba = theImage.PixelColor (Standard_Integer(aCol), Standard_Integer(aRow));
624           const NCollection_Vec4<float>& aPixel     = aPixelRgba;
625           if (aPixel[0] != 0.0f
626            || aPixel[1] != 0.0f
627            || aPixel[2] != 0.0f)
628           {
629             theImage.SetPixelColor (int(aCol), int(aRow), aWhiteRgba);
630           }
631         }
632       }
633       break;
634     }
635   }
636 }