1 // Created on: 2010-07-18
2 // Created by: Kirill GAVRILOV
3 // Copyright (c) 2010-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <Image_PixMap.hxx>
17 #include <NCollection_AlignedAllocator.hxx>
18 #include <Standard_ProgramError.hxx>
22 IMPLEMENT_STANDARD_RTTIEXT(Image_PixMap,Standard_Transient)
24 // =======================================================================
25 // function : Image_PixMap
27 // =======================================================================
28 Image_PixMap::Image_PixMap()
29 : myImgFormat (Image_Format_Gray)
34 // =======================================================================
35 // function : ~Image_PixMap
37 // =======================================================================
38 Image_PixMap::~Image_PixMap()
43 Standard_Size Image_PixMap::SizePixelBytes (const Image_Format thePixelFormat)
45 switch (thePixelFormat)
47 case Image_Format_GrayF:
48 case Image_Format_AlphaF:
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:
59 case Image_Format_RGB32:
60 case Image_Format_BGR32:
62 case Image_Format_RGB:
63 case Image_Format_BGR:
65 case Image_Format_Gray:
66 case Image_Format_Alpha:
68 case Image_Format_UNKNOWN:
74 // =======================================================================
75 // function : SetFormat
77 // =======================================================================
78 void Image_PixMap::SetFormat (Image_Format thePixelFormat)
80 if (myImgFormat == thePixelFormat)
86 && SizePixelBytes (myImgFormat) != SizePixelBytes (thePixelFormat))
88 throw Standard_ProgramError("Image_PixMap::SetFormat() - incompatible pixel format");
92 myImgFormat = thePixelFormat;
95 // =======================================================================
96 // function : InitWrapper
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)
106 myImgFormat = thePixelFormat;
107 if ((theSizeX == 0) || (theSizeY == 0) || (theDataPtr == NULL))
112 Handle(NCollection_BaseAllocator) anEmptyAlloc;
113 myData.Init (anEmptyAlloc, Image_PixMap::SizePixelBytes (thePixelFormat),
114 theSizeX, theSizeY, theSizeRowBytes, theDataPtr);
118 // =======================================================================
119 // function : InitTrash
121 // =======================================================================
122 bool Image_PixMap::InitTrash (Image_Format thePixelFormat,
123 const Standard_Size theSizeX,
124 const Standard_Size theSizeY,
125 const Standard_Size theSizeRowBytes)
128 myImgFormat = thePixelFormat;
129 if ((theSizeX == 0) || (theSizeY == 0))
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();
142 // =======================================================================
143 // function : InitZero
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)
152 if (!InitTrash (thePixelFormat, theSizeX, theSizeY, theSizeRowBytes))
156 memset (myData.ChangeData(), (int )theValue, SizeBytes());
160 // =======================================================================
161 // function : InitCopy
163 // =======================================================================
164 bool Image_PixMap::InitCopy (const Image_PixMap& theCopy)
166 if (&theCopy == this)
168 // self-copying disallowed
171 if (InitTrash (theCopy.myImgFormat, theCopy.SizeX(), theCopy.SizeY(), theCopy.SizeRowBytes()))
173 memcpy (myData.ChangeData(), theCopy.myData.Data(), theCopy.SizeBytes());
179 // =======================================================================
182 // =======================================================================
183 void Image_PixMap::Clear()
185 Handle(NCollection_BaseAllocator) anEmptyAlloc;
186 myData.Init (anEmptyAlloc, Image_PixMap::SizePixelBytes (myImgFormat),
190 // =======================================================================
191 // function : PixelColor
193 // =======================================================================
194 Quantity_ColorRGBA Image_PixMap::PixelColor (const Standard_Integer theX,
195 const Standard_Integer theY) const
198 || theX < 0 || (Standard_Size )theX >= SizeX()
199 || theY < 0 || (Standard_Size )theY >= SizeY())
201 return Quantity_ColorRGBA (0.0f, 0.0f, 0.0f, 0.0f); // transparent
206 case Image_Format_GrayF:
208 const Standard_ShortReal& aPixel = Value<Standard_ShortReal> (theY, theX);
209 return Quantity_ColorRGBA (NCollection_Vec4<float> (aPixel, aPixel, aPixel, 1.0f)); // opaque
211 case Image_Format_AlphaF:
213 const Standard_ShortReal& aPixel = Value<Standard_ShortReal> (theY, theX);
214 return Quantity_ColorRGBA (NCollection_Vec4<float> (1.0f, 1.0f, 1.0f, aPixel));
216 case Image_Format_RGBAF:
218 const Image_ColorRGBAF& aPixel = Value<Image_ColorRGBAF> (theY, theX);
219 return Quantity_ColorRGBA (NCollection_Vec4<float> (aPixel.r(), aPixel.g(), aPixel.b(), aPixel.a()));
221 case Image_Format_BGRAF:
223 const Image_ColorBGRAF& aPixel = Value<Image_ColorBGRAF> (theY, theX);
224 return Quantity_ColorRGBA (NCollection_Vec4<float> (aPixel.r(), aPixel.g(), aPixel.b(), aPixel.a()));
226 case Image_Format_RGBF:
228 const Image_ColorRGBF& aPixel = Value<Image_ColorRGBF> (theY, theX);
229 return Quantity_ColorRGBA (NCollection_Vec4<float> (aPixel.r(), aPixel.g(), aPixel.b(), 1.0f)); // opaque
231 case Image_Format_BGRF:
233 const Image_ColorBGRF& aPixel = Value<Image_ColorBGRF> (theY, theX);
234 return Quantity_ColorRGBA (NCollection_Vec4<float> (aPixel.r(), aPixel.g(), aPixel.b(), 1.0f)); // opaque
236 case Image_Format_RGBA:
238 const Image_ColorRGBA& aPixel = Value<Image_ColorRGBA> (theY, theX);
239 return Quantity_ColorRGBA (float(aPixel.r()) / 255.0f, float(aPixel.g()) / 255.0f, float(aPixel.b()) / 255.0f, float(aPixel.a()) / 255.0f);
241 case Image_Format_BGRA:
243 const Image_ColorBGRA& aPixel = Value<Image_ColorBGRA> (theY, theX);
244 return Quantity_ColorRGBA (float(aPixel.r()) / 255.0f, float(aPixel.g()) / 255.0f, float(aPixel.b()) / 255.0f, float(aPixel.a()) / 255.0f);
246 case Image_Format_RGB32:
248 const Image_ColorRGB32& aPixel = Value<Image_ColorRGB32> (theY, theX);
249 return Quantity_ColorRGBA (float(aPixel.r()) / 255.0f, float(aPixel.g()) / 255.0f, float(aPixel.b()) / 255.0f, 1.0f); // opaque
251 case Image_Format_BGR32:
253 const Image_ColorBGR32& aPixel = Value<Image_ColorBGR32> (theY, theX);
254 return Quantity_ColorRGBA (float(aPixel.r()) / 255.0f, float(aPixel.g()) / 255.0f, float(aPixel.b()) / 255.0f, 1.0f); // opaque
256 case Image_Format_RGB:
258 const Image_ColorRGB& aPixel = Value<Image_ColorRGB> (theY, theX);
259 return Quantity_ColorRGBA (float(aPixel.r()) / 255.0f, float(aPixel.g()) / 255.0f, float(aPixel.b()) / 255.0f, 1.0f); // opaque
261 case Image_Format_BGR:
263 const Image_ColorBGR& aPixel = Value<Image_ColorBGR> (theY, theX);
264 return Quantity_ColorRGBA (float(aPixel.r()) / 255.0f, float(aPixel.g()) / 255.0f, float(aPixel.b()) / 255.0f, 1.0f); // opaque
266 case Image_Format_Gray:
268 const Standard_Byte& aPixel = Value<Standard_Byte> (theY, theX);
269 return Quantity_ColorRGBA (float(aPixel) / 255.0f, float(aPixel) / 255.0f, float(aPixel) / 255.0f, 1.0f); // opaque
271 case Image_Format_Alpha:
273 const Standard_Byte& aPixel = Value<Standard_Byte> (theY, theX);
274 return Quantity_ColorRGBA (1.0f, 1.0f, 1.0f, float(aPixel) / 255.0f);
276 case Image_Format_UNKNOWN:
282 // unsupported image type
283 return Quantity_ColorRGBA (0.0f, 0.0f, 0.0f, 0.0f); // transparent
286 // =======================================================================
287 // function : SetPixelColor
289 // =======================================================================
290 void Image_PixMap::SetPixelColor (const Standard_Integer theX,
291 const Standard_Integer theY,
292 const Quantity_ColorRGBA& theColor)
295 || theX < 0 || Standard_Size(theX) >= SizeX()
296 || theY < 0 || Standard_Size(theY) >= SizeY())
301 const NCollection_Vec4<float>& aColor = theColor;
304 case Image_Format_GrayF:
306 ChangeValue<Standard_ShortReal> (theY, theX) = aColor.r();
309 case Image_Format_AlphaF:
311 ChangeValue<Standard_ShortReal> (theY, theX) = aColor.a();
314 case Image_Format_RGBAF:
316 Image_ColorRGBAF& aPixel = ChangeValue<Image_ColorRGBAF> (theY, theX);
317 aPixel.r() = aColor.r();
318 aPixel.g() = aColor.g();
319 aPixel.b() = aColor.b();
320 aPixel.a() = aColor.a();
323 case Image_Format_BGRAF:
325 Image_ColorBGRAF& aPixel = ChangeValue<Image_ColorBGRAF> (theY, theX);
326 aPixel.r() = aColor.r();
327 aPixel.g() = aColor.g();
328 aPixel.b() = aColor.b();
329 aPixel.a() = aColor.a();
332 case Image_Format_RGBF:
334 Image_ColorRGBF& aPixel = ChangeValue<Image_ColorRGBF> (theY, theX);
335 aPixel.r() = aColor.r();
336 aPixel.g() = aColor.g();
337 aPixel.b() = aColor.b();
340 case Image_Format_BGRF:
342 Image_ColorBGRF& aPixel = ChangeValue<Image_ColorBGRF> (theY, theX);
343 aPixel.r() = aColor.r();
344 aPixel.g() = aColor.g();
345 aPixel.b() = aColor.b();
348 case Image_Format_RGBA:
350 Image_ColorRGBA& aPixel = ChangeValue<Image_ColorRGBA> (theY, theX);
351 aPixel.r() = Standard_Byte(aColor.r() * 255.0f);
352 aPixel.g() = Standard_Byte(aColor.g() * 255.0f);
353 aPixel.b() = Standard_Byte(aColor.b() * 255.0f);
354 aPixel.a() = Standard_Byte(aColor.a() * 255.0f);
357 case Image_Format_BGRA:
359 Image_ColorBGRA& aPixel = ChangeValue<Image_ColorBGRA> (theY, theX);
360 aPixel.r() = Standard_Byte(aColor.r() * 255.0f);
361 aPixel.g() = Standard_Byte(aColor.g() * 255.0f);
362 aPixel.b() = Standard_Byte(aColor.b() * 255.0f);
363 aPixel.a() = Standard_Byte(aColor.a() * 255.0f);
366 case Image_Format_RGB32:
368 Image_ColorRGB32& aPixel = ChangeValue<Image_ColorRGB32> (theY, theX);
369 aPixel.r() = Standard_Byte(aColor.r() * 255.0f);
370 aPixel.g() = Standard_Byte(aColor.g() * 255.0f);
371 aPixel.b() = Standard_Byte(aColor.b() * 255.0f);
375 case Image_Format_BGR32:
377 Image_ColorBGR32& aPixel = ChangeValue<Image_ColorBGR32> (theY, theX);
378 aPixel.r() = Standard_Byte(aColor.r() * 255.0f);
379 aPixel.g() = Standard_Byte(aColor.g() * 255.0f);
380 aPixel.b() = Standard_Byte(aColor.b() * 255.0f);
384 case Image_Format_RGB:
386 Image_ColorRGB& aPixel = ChangeValue<Image_ColorRGB> (theY, theX);
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);
392 case Image_Format_BGR:
394 Image_ColorBGR& aPixel = ChangeValue<Image_ColorBGR> (theY, theX);
395 aPixel.r() = Standard_Byte(aColor.r() * 255.0f);
396 aPixel.g() = Standard_Byte(aColor.g() * 255.0f);
397 aPixel.b() = Standard_Byte(aColor.b() * 255.0f);
400 case Image_Format_Gray:
402 ChangeValue<Standard_Byte> (theY, theX) = Standard_Byte(aColor.r() * 255.0f);
405 case Image_Format_Alpha:
407 ChangeValue<Standard_Byte> (theY, theX) = Standard_Byte(aColor.a() * 255.0f);
410 case Image_Format_UNKNOWN:
417 // =======================================================================
418 // function : SwapRgbaBgra
420 // =======================================================================
421 bool Image_PixMap::SwapRgbaBgra (Image_PixMap& theImage)
423 switch (theImage.Format())
425 case Image_Format_BGR32:
426 case Image_Format_RGB32:
427 case Image_Format_BGRA:
428 case Image_Format_RGBA:
430 const bool toResetAlpha = theImage.Format() == Image_Format_BGR32
431 || theImage.Format() == Image_Format_RGB32;
432 for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
434 for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol)
436 Image_ColorRGBA& aPixel = theImage.ChangeValue<Image_ColorRGBA> (aRow, aCol);
437 Image_ColorBGRA aPixelCopy = theImage.Value <Image_ColorBGRA> (aRow, aCol);
438 aPixel.r() = aPixelCopy.r();
439 aPixel.g() = aPixelCopy.g();
440 aPixel.b() = aPixelCopy.b();
449 case Image_Format_BGR:
450 case Image_Format_RGB:
452 for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
454 for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol)
456 Image_ColorRGB& aPixel = theImage.ChangeValue<Image_ColorRGB> (aRow, aCol);
457 Image_ColorBGR aPixelCopy = theImage.Value <Image_ColorBGR> (aRow, aCol);
458 aPixel.r() = aPixelCopy.r();
459 aPixel.g() = aPixelCopy.g();
460 aPixel.b() = aPixelCopy.b();
465 case Image_Format_BGRF:
466 case Image_Format_RGBF:
467 case Image_Format_BGRAF:
468 case Image_Format_RGBAF:
470 for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
472 for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol)
474 Image_ColorRGBF& aPixel = theImage.ChangeValue<Image_ColorRGBF> (aRow, aCol);
475 Image_ColorBGRF aPixelCopy = theImage.Value <Image_ColorBGRF> (aRow, aCol);
476 aPixel.r() = aPixelCopy.r();
477 aPixel.g() = aPixelCopy.g();
478 aPixel.b() = aPixelCopy.b();
483 default: return false;
487 // =======================================================================
488 // function : ToBlackWhite
490 // =======================================================================
491 void Image_PixMap::ToBlackWhite (Image_PixMap& theImage)
493 switch (theImage.Format())
495 case Image_Format_Gray:
496 case Image_Format_Alpha:
498 for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
500 for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol)
502 unsigned char& aPixel = theImage.ChangeValue<unsigned char> (aRow, aCol);
511 case Image_Format_RGB:
512 case Image_Format_BGR:
513 case Image_Format_RGB32:
514 case Image_Format_BGR32:
515 case Image_Format_RGBA:
516 case Image_Format_BGRA:
518 const NCollection_Vec3<unsigned char> aWhite24 (255, 255, 255);
519 for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
521 for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol)
523 NCollection_Vec3<unsigned char>& aPixel = theImage.ChangeValue< NCollection_Vec3<unsigned char> > (aRow, aCol);
536 const Quantity_ColorRGBA aWhiteRgba (1.0f, 1.0f, 1.0f, 1.0f);
537 for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
539 for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol)
541 const Quantity_ColorRGBA aPixelRgba = theImage.PixelColor (Standard_Integer(aCol), Standard_Integer(aRow));
542 const NCollection_Vec4<float>& aPixel = aPixelRgba;
543 if (aPixel[0] != 0.0f
545 || aPixel[2] != 0.0f)
547 theImage.SetPixelColor (int(aCol), int(aRow), aWhiteRgba);