0028316: Coding Rules - Elimilate confusing aliases of Standard_Real type in V3d_View
[occt.git] / src / Image / Image_PixMap.cxx
CommitLineData
6aca4d39 1// Created on: 2010-07-18
692613e5 2// Created by: Kirill GAVRILOV
6aca4d39 3// Copyright (c) 2010-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 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
973c2be1 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.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
b311480e 15
692613e5 16#include <Image_PixMap.hxx>
ca0c0b11 17#include <NCollection_AlignedAllocator.hxx>
076ca35c 18#include <Standard_ProgramError.hxx>
7fd59977 19
a096a7a5 20#include <algorithm>
21
92efcf78 22IMPLEMENT_STANDARD_RTTIEXT(Image_PixMap,Standard_Transient)
23
692613e5 24// =======================================================================
25// function : Image_PixMap
26// purpose :
27// =======================================================================
28Image_PixMap::Image_PixMap()
dc858f4c 29: myImgFormat (Image_Format_Gray)
692613e5 30{
ca0c0b11 31 //
692613e5 32}
7fd59977 33
692613e5 34// =======================================================================
35// function : ~Image_PixMap
36// purpose :
37// =======================================================================
38Image_PixMap::~Image_PixMap()
39{
40 Clear();
41}
7fd59977 42
dc858f4c 43Standard_Size Image_PixMap::SizePixelBytes (const Image_Format thePixelFormat)
7fd59977 44{
692613e5 45 switch (thePixelFormat)
7fd59977 46 {
dc858f4c 47 case Image_Format_GrayF:
48 case Image_Format_AlphaF:
692613e5 49 return sizeof(float);
dc858f4c 50 case Image_Format_RGBAF:
51 case Image_Format_BGRAF:
692613e5 52 return sizeof(float) * 4;
dc858f4c 53 case Image_Format_RGBF:
54 case Image_Format_BGRF:
692613e5 55 return sizeof(float) * 3;
dc858f4c 56 case Image_Format_RGBA:
57 case Image_Format_BGRA:
692613e5 58 return 4;
dc858f4c 59 case Image_Format_RGB32:
60 case Image_Format_BGR32:
692613e5 61 return 4;
dc858f4c 62 case Image_Format_RGB:
63 case Image_Format_BGR:
692613e5 64 return 3;
dc858f4c 65 case Image_Format_Gray:
66 case Image_Format_Alpha:
076ca35c 67 return 1;
dc858f4c 68 case Image_Format_UNKNOWN:
692613e5 69 return 1;
7fd59977 70 }
076ca35c 71 return 1;
7fd59977 72}
73
692613e5 74// =======================================================================
076ca35c 75// function : SetFormat
692613e5 76// purpose :
77// =======================================================================
dc858f4c 78void Image_PixMap::SetFormat (Image_Format thePixelFormat)
7fd59977 79{
076ca35c 80 if (myImgFormat == thePixelFormat)
81 {
82 return;
83 }
84
85 if (!IsEmpty()
86 && SizePixelBytes (myImgFormat) != SizePixelBytes (thePixelFormat))
87 {
9775fa61 88 throw Standard_ProgramError("Image_PixMap::SetFormat() - incompatible pixel format");
076ca35c 89 return;
90 }
91
ca0c0b11 92 myImgFormat = thePixelFormat;
7fd59977 93}
94
692613e5 95// =======================================================================
96// function : InitWrapper
97// purpose :
98// =======================================================================
dc858f4c 99bool 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)
7fd59977 104{
ca0c0b11 105 Clear();
106 myImgFormat = thePixelFormat;
692613e5 107 if ((theSizeX == 0) || (theSizeY == 0) || (theDataPtr == NULL))
7fd59977 108 {
692613e5 109 return false;
7fd59977 110 }
ca0c0b11 111
112 Handle(NCollection_BaseAllocator) anEmptyAlloc;
113 myData.Init (anEmptyAlloc, Image_PixMap::SizePixelBytes (thePixelFormat),
114 theSizeX, theSizeY, theSizeRowBytes, theDataPtr);
692613e5 115 return true;
116}
7fd59977 117
692613e5 118// =======================================================================
119// function : InitTrash
120// purpose :
121// =======================================================================
dc858f4c 122bool Image_PixMap::InitTrash (Image_Format thePixelFormat,
123 const Standard_Size theSizeX,
124 const Standard_Size theSizeY,
125 const Standard_Size theSizeRowBytes)
692613e5 126{
ca0c0b11 127 Clear();
128 myImgFormat = thePixelFormat;
692613e5 129 if ((theSizeX == 0) || (theSizeY == 0))
7fd59977 130 {
692613e5 131 return false;
7fd59977 132 }
ca0c0b11 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();
7fd59977 140}
141
692613e5 142// =======================================================================
143// function : InitZero
144// purpose :
145// =======================================================================
dc858f4c 146bool 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)
7fd59977 151{
692613e5 152 if (!InitTrash (thePixelFormat, theSizeX, theSizeY, theSizeRowBytes))
153 {
154 return false;
155 }
ca0c0b11 156 memset (myData.ChangeData(), (int )theValue, SizeBytes());
692613e5 157 return true;
7fd59977 158}
159
692613e5 160// =======================================================================
161// function : InitCopy
162// purpose :
163// =======================================================================
164bool Image_PixMap::InitCopy (const Image_PixMap& theCopy)
7fd59977 165{
692613e5 166 if (&theCopy == this)
7fd59977 167 {
692613e5 168 // self-copying disallowed
169 return false;
7fd59977 170 }
ca0c0b11 171 if (InitTrash (theCopy.myImgFormat, theCopy.SizeX(), theCopy.SizeY(), theCopy.SizeRowBytes()))
692613e5 172 {
ca0c0b11 173 memcpy (myData.ChangeData(), theCopy.myData.Data(), theCopy.SizeBytes());
692613e5 174 return true;
175 }
176 return false;
7fd59977 177}
178
85e096c3 179// =======================================================================
692613e5 180// function : Clear
85e096c3 181// purpose :
182// =======================================================================
ca0c0b11 183void Image_PixMap::Clear()
7fd59977 184{
ca0c0b11 185 Handle(NCollection_BaseAllocator) anEmptyAlloc;
186 myData.Init (anEmptyAlloc, Image_PixMap::SizePixelBytes (myImgFormat),
187 0, 0, 0, NULL);
85e096c3 188}
189
190// =======================================================================
191// function : PixelColor
192// purpose :
193// =======================================================================
194Quantity_Color Image_PixMap::PixelColor (const Standard_Integer theX,
195 const Standard_Integer theY,
ee2be2a8 196 Standard_Real& theAlpha) const
85e096c3 197{
ca0c0b11 198 if (IsEmpty()
199 || theX < 0 || (Standard_Size )theX >= SizeX()
200 || theY < 0 || (Standard_Size )theY >= SizeY())
7fd59977 201 {
85e096c3 202 theAlpha = 0.0; // transparent
7fd59977 203 return Quantity_Color (0.0, 0.0, 0.0, Quantity_TOC_RGB);
204 }
692613e5 205
206 switch (myImgFormat)
7fd59977 207 {
dc858f4c 208 case Image_Format_GrayF:
692613e5 209 {
210 const Standard_ShortReal& aPixel = Value<Standard_ShortReal> (theY, theX);
211 theAlpha = 1.0; // opaque
ee2be2a8 212 return Quantity_Color (aPixel, aPixel, aPixel, Quantity_TOC_RGB);
692613e5 213 }
dc858f4c 214 case Image_Format_AlphaF:
076ca35c 215 {
216 const Standard_ShortReal& aPixel = Value<Standard_ShortReal> (theY, theX);
217 theAlpha = aPixel;
218 return Quantity_Color (1.0, 1.0, 1.0, Quantity_TOC_RGB);
219 }
dc858f4c 220 case Image_Format_RGBAF:
692613e5 221 {
222 const Image_ColorRGBAF& aPixel = Value<Image_ColorRGBAF> (theY, theX);
223 theAlpha = aPixel.a();
ee2be2a8 224 return Quantity_Color (aPixel.r(), aPixel.g(), aPixel.b(), Quantity_TOC_RGB);
692613e5 225 }
dc858f4c 226 case Image_Format_BGRAF:
692613e5 227 {
228 const Image_ColorBGRAF& aPixel = Value<Image_ColorBGRAF> (theY, theX);
229 theAlpha = aPixel.a();
ee2be2a8 230 return Quantity_Color (aPixel.r(), aPixel.g(), aPixel.b(), Quantity_TOC_RGB);
692613e5 231 }
dc858f4c 232 case Image_Format_RGBF:
692613e5 233 {
234 const Image_ColorRGBF& aPixel = Value<Image_ColorRGBF> (theY, theX);
235 theAlpha = 1.0; // opaque
ee2be2a8 236 return Quantity_Color (aPixel.r(), aPixel.g(), aPixel.b(), Quantity_TOC_RGB);
692613e5 237 }
dc858f4c 238 case Image_Format_BGRF:
7fd59977 239 {
692613e5 240 const Image_ColorBGRF& aPixel = Value<Image_ColorBGRF> (theY, theX);
241 theAlpha = 1.0; // opaque
ee2be2a8 242 return Quantity_Color (aPixel.r(), aPixel.g(), aPixel.b(), Quantity_TOC_RGB);
692613e5 243 }
dc858f4c 244 case Image_Format_RGBA:
692613e5 245 {
246 const Image_ColorRGBA& aPixel = Value<Image_ColorRGBA> (theY, theX);
247 theAlpha = Standard_Real (aPixel.a()) / 255.0;
ee2be2a8 248 return Quantity_Color (Standard_Real (aPixel.r()) / 255.0, Standard_Real (aPixel.g()) / 255.0, Standard_Real (aPixel.b()) / 255.0, Quantity_TOC_RGB);
692613e5 249 }
dc858f4c 250 case Image_Format_BGRA:
692613e5 251 {
252 const Image_ColorBGRA& aPixel = Value<Image_ColorBGRA> (theY, theX);
253 theAlpha = Standard_Real (aPixel.a()) / 255.0;
ee2be2a8 254 return Quantity_Color (Standard_Real (aPixel.r()) / 255.0, Standard_Real (aPixel.g()) / 255.0, Standard_Real (aPixel.b() / 255.0), Quantity_TOC_RGB);
692613e5 255 }
dc858f4c 256 case Image_Format_RGB32:
692613e5 257 {
258 const Image_ColorRGB32& aPixel = Value<Image_ColorRGB32> (theY, theX);
259 theAlpha = 1.0; // opaque
ee2be2a8 260 return Quantity_Color (Standard_Real (aPixel.r()) / 255.0, Standard_Real (aPixel.g()) / 255.0, Standard_Real (aPixel.b()) / 255.0, Quantity_TOC_RGB);
692613e5 261 }
dc858f4c 262 case Image_Format_BGR32:
692613e5 263 {
264 const Image_ColorBGR32& aPixel = Value<Image_ColorBGR32> (theY, theX);
265 theAlpha = 1.0; // opaque
ee2be2a8 266 return Quantity_Color (Standard_Real (aPixel.r()) / 255.0, Standard_Real (aPixel.g()) / 255.0, Standard_Real (aPixel.b()) / 255.0, Quantity_TOC_RGB);
692613e5 267 }
dc858f4c 268 case Image_Format_RGB:
692613e5 269 {
270 const Image_ColorRGB& aPixel = Value<Image_ColorRGB> (theY, theX);
271 theAlpha = 1.0; // opaque
ee2be2a8 272 return Quantity_Color (Standard_Real (aPixel.r()) / 255.0, Standard_Real (aPixel.g()) / 255.0, Standard_Real (aPixel.b()) / 255.0, Quantity_TOC_RGB);
692613e5 273 }
dc858f4c 274 case Image_Format_BGR:
692613e5 275 {
276 const Image_ColorBGR& aPixel = Value<Image_ColorBGR> (theY, theX);
277 theAlpha = 1.0; // opaque
ee2be2a8 278 return Quantity_Color (Standard_Real (aPixel.r()) / 255.0, Standard_Real (aPixel.g()) / 255.0, Standard_Real (aPixel.b()) / 255.0, Quantity_TOC_RGB);
692613e5 279 }
dc858f4c 280 case Image_Format_Gray:
692613e5 281 {
282 const Standard_Byte& aPixel = Value<Standard_Byte> (theY, theX);
283 theAlpha = 1.0; // opaque
ee2be2a8 284 return Quantity_Color (Standard_Real (aPixel) / 255.0, Standard_Real (aPixel) / 255.0, Standard_Real (aPixel) / 255.0, Quantity_TOC_RGB);
692613e5 285 }
dc858f4c 286 case Image_Format_Alpha:
692613e5 287 {
076ca35c 288 const Standard_Byte& aPixel = Value<Standard_Byte> (theY, theX);
289 theAlpha = Standard_Real (aPixel) / 255.0;
290 return Quantity_Color (1.0, 1.0, 1.0, Quantity_TOC_RGB);
291 }
dc858f4c 292 case Image_Format_UNKNOWN:
076ca35c 293 {
294 break;
7fd59977 295 }
296 }
076ca35c 297
298 // unsupported image type
299 theAlpha = 0.0; // transparent
300 return Quantity_Color (0.0, 0.0, 0.0, Quantity_TOC_RGB);
7fd59977 301}
f9f740d6 302
303// =======================================================================
decdee7d 304// function : SetPixelColor
305// purpose :
306// =======================================================================
307void Image_PixMap::SetPixelColor (const Standard_Integer theX,
308 const Standard_Integer theY,
309 const NCollection_Vec4<float>& theColor)
310{
311 if (IsEmpty()
312 || theX < 0 || Standard_Size(theX) >= SizeX()
313 || theY < 0 || Standard_Size(theY) >= SizeY())
314 {
315 return;
316 }
317
318 switch (myImgFormat)
319 {
dc858f4c 320 case Image_Format_GrayF:
decdee7d 321 {
322 ChangeValue<Standard_ShortReal> (theY, theX) = theColor.r();
323 return;
324 }
dc858f4c 325 case Image_Format_AlphaF:
decdee7d 326 {
327 ChangeValue<Standard_ShortReal> (theY, theX) = theColor.a();
328 return;
329 }
dc858f4c 330 case Image_Format_RGBAF:
decdee7d 331 {
332 Image_ColorRGBAF& aPixel = ChangeValue<Image_ColorRGBAF> (theY, theX);
333 aPixel.r() = theColor.r();
334 aPixel.g() = theColor.g();
335 aPixel.b() = theColor.b();
336 aPixel.a() = theColor.a();
337 return;
338 }
dc858f4c 339 case Image_Format_BGRAF:
decdee7d 340 {
341 Image_ColorBGRAF& aPixel = ChangeValue<Image_ColorBGRAF> (theY, theX);
342 aPixel.r() = theColor.r();
343 aPixel.g() = theColor.g();
344 aPixel.b() = theColor.b();
345 aPixel.a() = theColor.a();
346 return;
347 }
dc858f4c 348 case Image_Format_RGBF:
decdee7d 349 {
350 Image_ColorRGBF& aPixel = ChangeValue<Image_ColorRGBF> (theY, theX);
351 aPixel.r() = theColor.r();
352 aPixel.g() = theColor.g();
353 aPixel.b() = theColor.b();
354 return;
355 }
dc858f4c 356 case Image_Format_BGRF:
decdee7d 357 {
358 Image_ColorBGRF& aPixel = ChangeValue<Image_ColorBGRF> (theY, theX);
359 aPixel.r() = theColor.r();
360 aPixel.g() = theColor.g();
361 aPixel.b() = theColor.b();
362 return;
363 }
dc858f4c 364 case Image_Format_RGBA:
decdee7d 365 {
366 Image_ColorRGBA& aPixel = ChangeValue<Image_ColorRGBA> (theY, theX);
367 aPixel.r() = Standard_Byte(theColor.r() * 255.0f);
368 aPixel.g() = Standard_Byte(theColor.g() * 255.0f);
369 aPixel.b() = Standard_Byte(theColor.b() * 255.0f);
370 aPixel.a() = Standard_Byte(theColor.a() * 255.0f);
371 return;
372 }
dc858f4c 373 case Image_Format_BGRA:
decdee7d 374 {
375 Image_ColorBGRA& aPixel = ChangeValue<Image_ColorBGRA> (theY, theX);
376 aPixel.r() = Standard_Byte(theColor.r() * 255.0f);
377 aPixel.g() = Standard_Byte(theColor.g() * 255.0f);
378 aPixel.b() = Standard_Byte(theColor.b() * 255.0f);
379 aPixel.a() = Standard_Byte(theColor.a() * 255.0f);
380 return;
381 }
dc858f4c 382 case Image_Format_RGB32:
decdee7d 383 {
384 Image_ColorRGB32& aPixel = ChangeValue<Image_ColorRGB32> (theY, theX);
385 aPixel.r() = Standard_Byte(theColor.r() * 255.0f);
386 aPixel.g() = Standard_Byte(theColor.g() * 255.0f);
387 aPixel.b() = Standard_Byte(theColor.b() * 255.0f);
388 aPixel.a_() = 255;
389 return;
390 }
dc858f4c 391 case Image_Format_BGR32:
decdee7d 392 {
393 Image_ColorBGR32& aPixel = ChangeValue<Image_ColorBGR32> (theY, theX);
394 aPixel.r() = Standard_Byte(theColor.r() * 255.0f);
395 aPixel.g() = Standard_Byte(theColor.g() * 255.0f);
396 aPixel.b() = Standard_Byte(theColor.b() * 255.0f);
397 aPixel.a_() = 255;
398 return;
399 }
dc858f4c 400 case Image_Format_RGB:
decdee7d 401 {
402 Image_ColorRGB& aPixel = ChangeValue<Image_ColorRGB> (theY, theX);
403 aPixel.r() = Standard_Byte(theColor.r() * 255.0f);
404 aPixel.g() = Standard_Byte(theColor.g() * 255.0f);
405 aPixel.b() = Standard_Byte(theColor.b() * 255.0f);
406 return;
407 }
dc858f4c 408 case Image_Format_BGR:
decdee7d 409 {
410 Image_ColorBGR& aPixel = ChangeValue<Image_ColorBGR> (theY, theX);
411 aPixel.r() = Standard_Byte(theColor.r() * 255.0f);
412 aPixel.g() = Standard_Byte(theColor.g() * 255.0f);
413 aPixel.b() = Standard_Byte(theColor.b() * 255.0f);
414 return;
415 }
dc858f4c 416 case Image_Format_Gray:
decdee7d 417 {
418 ChangeValue<Standard_Byte> (theY, theX) = Standard_Byte(theColor.r() * 255.0f);
419 return;
420 }
dc858f4c 421 case Image_Format_Alpha:
decdee7d 422 {
423 ChangeValue<Standard_Byte> (theY, theX) = Standard_Byte(theColor.a() * 255.0f);
424 return;
425 }
dc858f4c 426 case Image_Format_UNKNOWN:
decdee7d 427 {
428 return;
429 }
430 }
431}
432
433// =======================================================================
f9f740d6 434// function : SwapRgbaBgra
435// purpose :
436// =======================================================================
437bool Image_PixMap::SwapRgbaBgra (Image_PixMap& theImage)
438{
439 switch (theImage.Format())
440 {
dc858f4c 441 case Image_Format_BGR32:
442 case Image_Format_RGB32:
443 case Image_Format_BGRA:
444 case Image_Format_RGBA:
f9f740d6 445 {
dc858f4c 446 const bool toResetAlpha = theImage.Format() == Image_Format_BGR32
447 || theImage.Format() == Image_Format_RGB32;
f9f740d6 448 for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
449 {
450 for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol)
451 {
452 Image_ColorRGBA& aPixel = theImage.ChangeValue<Image_ColorRGBA> (aRow, aCol);
453 Image_ColorBGRA aPixelCopy = theImage.Value <Image_ColorBGRA> (aRow, aCol);
454 aPixel.r() = aPixelCopy.r();
455 aPixel.g() = aPixelCopy.g();
456 aPixel.b() = aPixelCopy.b();
457 if (toResetAlpha)
458 {
459 aPixel.a() = 255;
460 }
461 }
462 }
463 return true;
464 }
dc858f4c 465 case Image_Format_BGR:
466 case Image_Format_RGB:
f9f740d6 467 {
468 for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
469 {
470 for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol)
471 {
472 Image_ColorRGB& aPixel = theImage.ChangeValue<Image_ColorRGB> (aRow, aCol);
473 Image_ColorBGR aPixelCopy = theImage.Value <Image_ColorBGR> (aRow, aCol);
474 aPixel.r() = aPixelCopy.r();
475 aPixel.g() = aPixelCopy.g();
476 aPixel.b() = aPixelCopy.b();
477 }
478 }
479 return true;
480 }
dc858f4c 481 case Image_Format_BGRF:
482 case Image_Format_RGBF:
483 case Image_Format_BGRAF:
484 case Image_Format_RGBAF:
f9f740d6 485 {
486 for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
487 {
488 for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol)
489 {
490 Image_ColorRGBF& aPixel = theImage.ChangeValue<Image_ColorRGBF> (aRow, aCol);
491 Image_ColorBGRF aPixelCopy = theImage.Value <Image_ColorBGRF> (aRow, aCol);
492 aPixel.r() = aPixelCopy.r();
493 aPixel.g() = aPixelCopy.g();
494 aPixel.b() = aPixelCopy.b();
495 }
496 }
497 return true;
498 }
499 default: return false;
500 }
501}