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