|
|
|||
Warning, file /include/opencascade/Image_PixMap.hxx was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 // Created on: 2012-07-18 0002 // Created by: Kirill GAVRILOV 0003 // Copyright (c) 2012-2014 OPEN CASCADE SAS 0004 // 0005 // This file is part of Open CASCADE Technology software library. 0006 // 0007 // This library is free software; you can redistribute it and/or modify it under 0008 // the terms of the GNU Lesser General Public License version 2.1 as published 0009 // by the Free Software Foundation, with special exception defined in the file 0010 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT 0011 // distribution for complete text of the license and disclaimer of any warranty. 0012 // 0013 // Alternatively, this file may be used under the terms of Open CASCADE 0014 // commercial license or contractual agreement. 0015 0016 #ifndef Image_PixMap_HeaderFile 0017 #define Image_PixMap_HeaderFile 0018 0019 #include <Image_CompressedFormat.hxx> 0020 #include <Image_PixMapData.hxx> 0021 #include <Standard_Transient.hxx> 0022 #include <Quantity_ColorRGBA.hxx> 0023 0024 //! Class represents packed image plane. 0025 class Image_PixMap : public Standard_Transient 0026 { 0027 DEFINE_STANDARD_RTTIEXT(Image_PixMap, Standard_Transient) 0028 public: 0029 //! Determine Big-Endian at runtime 0030 static inline bool IsBigEndianHost() 0031 { 0032 union { 0033 int myInt; 0034 char myChar[sizeof(int)]; 0035 } aUnion; 0036 0037 aUnion.myInt = 1; 0038 return !aUnion.myChar[0]; 0039 } 0040 0041 //! Return bytes reserved for one pixel (may include extra bytes for alignment). 0042 Standard_EXPORT static size_t SizePixelBytes(const Image_Format thePixelFormat); 0043 0044 //! Auxiliary method for swapping bytes between RGB and BGR formats. 0045 //! This method modifies the image data but does not change pixel format! 0046 //! Method will fail if pixel format is not one of the following: 0047 //! - Image_Format_RGB32 / Image_Format_BGR32 0048 //! - Image_Format_RGBA / Image_Format_BGRA 0049 //! - Image_Format_RGB / Image_Format_BGR 0050 //! - Image_Format_RGBF / Image_Format_BGRF 0051 //! - Image_Format_RGBAF / Image_Format_BGRAF 0052 Standard_EXPORT static bool SwapRgbaBgra(Image_PixMap& theImage); 0053 0054 //! Convert image to Black/White. 0055 Standard_EXPORT static void ToBlackWhite(Image_PixMap& theImage); 0056 0057 //! Reverse line order as it draws it from bottom to top. 0058 Standard_EXPORT static bool FlipY(Image_PixMap& theImage); 0059 0060 //! Return default image data allocator. 0061 Standard_EXPORT static const occ::handle<NCollection_BaseAllocator>& DefaultAllocator(); 0062 0063 //! Return string representation of pixel format. 0064 Standard_EXPORT static const char* ImageFormatToString(Image_Format theFormat); 0065 0066 //! Return string representation of compressed pixel format. 0067 Standard_EXPORT static const char* ImageFormatToString(Image_CompressedFormat theFormat); 0068 0069 //! Convert raw pixel value into Quantity_ColorRGBA. This function is relatively slow. 0070 //! @param[in] theRawValue pointer to pixel definition 0071 //! @param[in] theFormat pixel format 0072 //! @param[in] theToLinearize when TRUE, the color stored in non-linear color space (e.g. 0073 //! Image_Format_RGB) will be linearized 0074 //! @return the pixel color 0075 Standard_EXPORT static Quantity_ColorRGBA ColorFromRawPixel(const uint8_t* theRawValue, 0076 const Image_Format theFormat, 0077 const bool theToLinearize = false); 0078 0079 //! Set raw pixel value from Quantity_ColorRGBA. This function is relatively slow. 0080 //! @param[out] theRawValue pointer to pixel definition to modify 0081 //! @param[in] theFormat pixel format 0082 //! @param[in] theColor color value to convert from 0083 //! @param[in] theToDeLinearize when TRUE, the gamma correction will be applied for storing in 0084 //! non-linear color space (e.g. Image_Format_RGB) 0085 Standard_EXPORT static void ColorToRawPixel(uint8_t* theRawValue, 0086 const Image_Format theFormat, 0087 const Quantity_ColorRGBA& theColor, 0088 const bool theToDeLinearize = false); 0089 0090 public: // high-level API 0091 //! Return pixel format. 0092 Image_Format Format() const { return myImgFormat; } 0093 0094 //! Override pixel format specified by InitXXX() methods. 0095 //! Will throw exception if pixel size of new format is not equal to currently initialized format. 0096 //! Intended to switch formats indicating different interpretation of the same data 0097 //! (e.g. ImgGray and ImgAlpha). 0098 Standard_EXPORT void SetFormat(const Image_Format thePixelFormat); 0099 0100 //! Return image width in pixels. 0101 size_t Width() const { return myData.SizeX; } 0102 0103 //! Return image height in pixels. 0104 size_t Height() const { return myData.SizeY; } 0105 0106 //! Return image depth in pixels. 0107 size_t Depth() const { return myData.SizeZ; } 0108 0109 //! Return image width in pixels. 0110 size_t SizeX() const { return myData.SizeX; } 0111 0112 //! Return image height in pixels. 0113 size_t SizeY() const { return myData.SizeY; } 0114 0115 //! Return image depth in pixels. 0116 size_t SizeZ() const { return myData.SizeZ; } 0117 0118 //! Return image width x height x depth in pixels. 0119 NCollection_Vec3<size_t> SizeXYZ() const 0120 { 0121 return NCollection_Vec3<size_t>(myData.SizeX, myData.SizeY, myData.SizeZ); 0122 } 0123 0124 //! Return width / height. 0125 double Ratio() const { return (SizeY() > 0) ? (double(SizeX()) / double(SizeY())) : 1.0; } 0126 0127 //! Return true if data is NULL. 0128 bool IsEmpty() const { return myData.IsEmpty(); } 0129 0130 //! Empty constructor. Initialize the NULL image plane. 0131 Standard_EXPORT Image_PixMap(); 0132 0133 //! Destructor 0134 Standard_EXPORT ~Image_PixMap() override; 0135 0136 //! Returns the pixel color. This function is relatively slow. 0137 //! Beware that this method takes coordinates in opposite order in contrast to ::Value() and 0138 //! ::ChangeValue(). 0139 //! @param[in] theX column index from left, starting from 0 0140 //! @param[in] theY row index from top, starting from 0 0141 //! @param[in] theToLinearize when TRUE, the color stored in non-linear color space (e.g. 0142 //! Image_Format_RGB) will be linearized 0143 //! @return the pixel color 0144 Quantity_ColorRGBA PixelColor(int theX, int theY, bool theToLinearize = false) const 0145 { 0146 if (IsEmpty() || theX < 0 || (size_t)theX >= SizeX() || theY < 0 || (size_t)theY >= SizeY()) 0147 { 0148 return Quantity_ColorRGBA(0.0f, 0.0f, 0.0f, 0.0f); // transparent 0149 } 0150 0151 const uint8_t* aRawPixel = RawValueXY(theX, theY); 0152 return ColorFromRawPixel(aRawPixel, myImgFormat, theToLinearize); 0153 } 0154 0155 //! Sets the pixel color. This function is relatively slow. 0156 //! Beware that this method takes coordinates in opposite order in contrast to ::Value() and 0157 //! ::ChangeValue(). 0158 //! @param[in] theX column index from left 0159 //! @param[in] theY row index from top 0160 //! @param[in] theColor color to store 0161 //! @param[in] theToDeLinearize when TRUE, the gamma correction will be applied for storing in 0162 //! non-linear color space (e.g. Image_Format_RGB) 0163 void SetPixelColor(const int theX, 0164 const int theY, 0165 const Quantity_Color& theColor, 0166 const bool theToDeLinearize = false) 0167 { 0168 SetPixelColor(theX, theY, Quantity_ColorRGBA(theColor, 1.0f), theToDeLinearize); 0169 } 0170 0171 //! Sets the pixel color. This function is relatively slow. 0172 //! Beware that this method takes coordinates in opposite order in contrast to ::Value() and 0173 //! ::ChangeValue(). 0174 //! @param[in] theX column index from left 0175 //! @param[in] theY row index from top 0176 //! @param[in] theColor color to store 0177 //! @param[in] theToDeLinearize when TRUE, the gamma correction will be applied for storing in 0178 //! non-linear color space (e.g. Image_Format_RGB) 0179 void SetPixelColor(const int theX, 0180 const int theY, 0181 const Quantity_ColorRGBA& theColor, 0182 const bool theToDeLinearize = false) 0183 { 0184 if (IsEmpty() || theX < 0 || size_t(theX) >= SizeX() || theY < 0 || size_t(theY) >= SizeY()) 0185 { 0186 return; 0187 } 0188 0189 uint8_t* aRawPixel = ChangeRawValueXY(theX, theY); 0190 ColorToRawPixel(aRawPixel, myImgFormat, theColor, theToDeLinearize); 0191 } 0192 0193 //! Initialize image plane as wrapper over alien data. 0194 //! Data will not be copied! Notice that caller should ensure 0195 //! that data pointer will not be released during this wrapper lifetime. 0196 //! You may call InitCopy() to perform data copying. 0197 Standard_EXPORT virtual bool InitWrapper(Image_Format thePixelFormat, 0198 uint8_t* theDataPtr, 0199 const size_t theSizeX, 0200 const size_t theSizeY, 0201 const size_t theSizeRowBytes = 0); 0202 0203 //! Initialize image plane with required dimensions. 0204 //! Memory will be left uninitialized (performance trick). 0205 Standard_EXPORT virtual bool InitTrash(Image_Format thePixelFormat, 0206 const size_t theSizeX, 0207 const size_t theSizeY, 0208 const size_t theSizeRowBytes = 0); 0209 0210 //! Initialize by copying data. 0211 //! If you want to copy alien data you should create wrapper using InitWrapper() before. 0212 Standard_EXPORT virtual bool InitCopy(const Image_PixMap& theCopy); 0213 0214 //! Initialize image plane with required dimensions. 0215 //! Buffer will be zeroed (black color for most formats). 0216 bool InitZero(Image_Format thePixelFormat, 0217 const size_t theSizeX, 0218 const size_t theSizeY, 0219 const size_t theSizeRowBytes = 0, 0220 const uint8_t theValue = 0) 0221 { 0222 return InitZero3D(thePixelFormat, 0223 NCollection_Vec3<size_t>(theSizeX, theSizeY, 1), 0224 theSizeRowBytes, 0225 theValue); 0226 } 0227 0228 //! Method correctly deallocate internal buffer. 0229 Standard_EXPORT virtual void Clear(); 0230 0231 public: 0232 //! Initialize 2D/3D image as wrapper over alien data. 0233 //! Data will not be copied! Notice that caller should ensure 0234 //! that data pointer will not be released during this wrapper lifetime. 0235 //! You may call InitCopy() to perform data copying. 0236 Standard_EXPORT virtual bool InitWrapper3D(Image_Format thePixelFormat, 0237 uint8_t* theDataPtr, 0238 const NCollection_Vec3<size_t>& theSizeXYZ, 0239 const size_t theSizeRowBytes = 0); 0240 0241 //! Initialize 2D/3D image with required dimensions. 0242 //! Memory will be left uninitialized (performance trick). 0243 Standard_EXPORT virtual bool InitTrash3D(Image_Format thePixelFormat, 0244 const NCollection_Vec3<size_t>& theSizeXYZ, 0245 const size_t theSizeRowBytes = 0); 0246 0247 //! Initialize 2D/3D image with required dimensions. 0248 //! Buffer will be zeroed (black color for most formats). 0249 Standard_EXPORT bool InitZero3D(Image_Format thePixelFormat, 0250 const NCollection_Vec3<size_t>& theSizeXYZ, 0251 const size_t theSizeRowBytes = 0, 0252 const uint8_t theValue = 0); 0253 0254 public: //! @name low-level API for batch-processing (pixels reading / comparison / modification) 0255 //! Returns TRUE if image data is stored from Top to the Down. 0256 //! By default Bottom Up order is used instead 0257 //! (topmost scanlines starts from the bottom in memory). 0258 //! which is most image frameworks naturally support. 0259 //! 0260 //! Notice that access methods within this class automatically 0261 //! convert input row-index to apply this flag! 0262 //! You should use this flag only if interconnect with alien APIs and buffers. 0263 //! @return true if image data is top-down 0264 bool IsTopDown() const { return myData.TopToDown == 1; } 0265 0266 //! Setup scanlines order in memory - top-down or bottom-up. 0267 //! Drawers should explicitly specify this value if current state IsTopDown() was ignored! 0268 //! @param theIsTopDown top-down flag 0269 void SetTopDown(const bool theIsTopDown) { myData.SetTopDown(theIsTopDown); } 0270 0271 //! Returns +1 if scanlines ordered in Top->Down order in memory and -1 otherwise. 0272 //! @return scanline increment for Top->Down iteration 0273 size_t TopDownInc() const { return myData.TopToDown; } 0274 0275 //! Return data pointer for low-level operations (copying entire buffer, parsing with extra tools 0276 //! etc.). 0277 const uint8_t* Data() const { return myData.Data(); } 0278 0279 //! Return data pointer for low-level operations (copying entire buffer, parsing with extra tools 0280 //! etc.). 0281 uint8_t* ChangeData() { return myData.ChangeData(); } 0282 0283 //! Return data pointer to requested row (first column). 0284 //! Indexation starts from 0. 0285 const uint8_t* Row(size_t theRow) const { return myData.Row(theRow); } 0286 0287 //! Return data pointer to requested row (first column). 0288 //! Indexation starts from 0. 0289 uint8_t* ChangeRow(size_t theRow) { return myData.ChangeRow(theRow); } 0290 0291 //! Return data pointer to requested 2D slice. 0292 //! Indexation starts from 0. 0293 const uint8_t* Slice(size_t theSlice) const { return myData.Slice(theSlice); } 0294 0295 //! Return data pointer to requested 2D slice. 0296 //! Indexation starts from 0. 0297 uint8_t* ChangeSlice(size_t theSlice) { return myData.ChangeSlice(theSlice); } 0298 0299 //! Return data pointer to requested row (first column). 0300 //! Indexation starts from 0. 0301 const uint8_t* SliceRow(size_t theSlice, size_t theRow) const 0302 { 0303 return myData.SliceRow(theSlice, theRow); 0304 } 0305 0306 //! Return data pointer to requested row (first column). 0307 //! Indexation starts from 0. 0308 uint8_t* ChangeSliceRow(size_t theSlice, size_t theRow) 0309 { 0310 return myData.ChangeSliceRow(theSlice, theRow); 0311 } 0312 0313 //! Return bytes reserved for one pixel (may include extra bytes for alignment). 0314 size_t SizePixelBytes() const { return myData.SizeBPP; } 0315 0316 //! Return bytes reserved per row. 0317 //! Could be larger than needed to store packed row (extra bytes for alignment etc.). 0318 size_t SizeRowBytes() const { return myData.SizeRowBytes; } 0319 0320 //! Return the extra bytes in the row. 0321 size_t RowExtraBytes() const { return SizeRowBytes() - SizeX() * SizePixelBytes(); } 0322 0323 //! Compute the maximal row alignment for current row size. 0324 //! @return maximal row alignment in bytes (up to 16 bytes). 0325 size_t MaxRowAligmentBytes() const { return myData.MaxRowAligmentBytes(); } 0326 0327 //! Return number of bytes per 2D slice. 0328 size_t SizeSliceBytes() const { return myData.SizeSliceBytes; } 0329 0330 //! Return buffer size 0331 size_t SizeBytes() const { return myData.Size(); } 0332 0333 public: 0334 //! Access image pixel with specified color type. 0335 //! Indexation starts from 0. 0336 //! This method does not perform any type checks - use on own risk (check Format() before)! 0337 //! WARNING: Input parameters are defined in the decreasing majority following memory layout - 0338 //! e.g. row first, column next. 0339 template <typename ColorType_t> 0340 const ColorType_t& Value(size_t theRow, size_t theCol) const 0341 { 0342 return *reinterpret_cast<const ColorType_t*>(myData.Value(theRow, theCol)); 0343 } 0344 0345 //! Access image pixel with specified color type. 0346 //! Indexation starts from 0. 0347 //! This method does not perform any type checks - use on own risk (check Format() before)! 0348 //! WARNING: Input parameters are defined in the decreasing majority following memory layout - 0349 //! e.g. row first, column next. 0350 template <typename ColorType_t> 0351 ColorType_t& ChangeValue(size_t theRow, size_t theCol) 0352 { 0353 return *reinterpret_cast<ColorType_t*>(myData.ChangeValue(theRow, theCol)); 0354 } 0355 0356 //! Access image pixel as raw data pointer. 0357 //! Indexation starts from 0. 0358 //! This method does not perform any type checks - use on own risk (check Format() before)! 0359 //! WARNING: Input parameters are defined in the decreasing majority following memory layout - 0360 //! e.g. row first, column next. 0361 const uint8_t* RawValue(size_t theRow, size_t theCol) const 0362 { 0363 return myData.Value(theRow, theCol); 0364 } 0365 0366 //! Access image pixel as raw data pointer. 0367 //! Indexation starts from 0. 0368 //! This method does not perform any type checks - use on own risk (check Format() before)! 0369 //! WARNING: Input parameters are defined in the decreasing majority following memory layout - 0370 //! e.g. row first, column next. 0371 uint8_t* ChangeRawValue(size_t theRow, size_t theCol) 0372 { 0373 return myData.ChangeValue(theRow, theCol); 0374 } 0375 0376 //! Access image pixel with specified color type. 0377 //! Indexation starts from 0. 0378 //! This method does not perform any type checks - use on own risk (check Format() before)! 0379 //! WARNING: Input parameters are defined in traditional X, Y order. 0380 template <typename ColorType_t> 0381 const ColorType_t& ValueXY(size_t theX, size_t theY) const 0382 { 0383 return *reinterpret_cast<const ColorType_t*>(myData.ValueXY(theX, theY)); 0384 } 0385 0386 //! Access image pixel with specified color type. 0387 //! Indexation starts from 0. 0388 //! This method does not perform any type checks - use on own risk (check Format() before)! 0389 //! WARNING: Input parameters are defined in traditional X, Y order. 0390 template <typename ColorType_t> 0391 ColorType_t& ChangeValueXY(size_t theX, size_t theY) 0392 { 0393 return *reinterpret_cast<ColorType_t*>(myData.ChangeValueXY(theX, theY)); 0394 } 0395 0396 //! Access image pixel as raw data pointer. 0397 //! Indexation starts from 0. 0398 //! This method does not perform any type checks - use on own risk (check Format() before)! 0399 //! WARNING: Input parameters are defined in traditional X, Y order. 0400 const uint8_t* RawValueXY(size_t theX, size_t theY) const { return myData.ValueXY(theX, theY); } 0401 0402 //! Access image pixel as raw data pointer. 0403 //! Indexation starts from 0. 0404 //! This method does not perform any type checks - use on own risk (check Format() before)! 0405 //! WARNING: Input parameters are defined in traditional X, Y order. 0406 uint8_t* ChangeRawValueXY(size_t theX, size_t theY) { return myData.ChangeValueXY(theX, theY); } 0407 0408 public: 0409 //! Access image pixel with specified color type. 0410 //! Indexation starts from 0. 0411 //! This method does not perform any type checks - use on own risk (check Format() before)! 0412 //! WARNING: Input parameters are defined in traditional X, Y, Z order. 0413 template <typename ColorType_t> 0414 const ColorType_t& ValueXYZ(size_t theX, size_t theY, size_t theZ) const 0415 { 0416 return *reinterpret_cast<const ColorType_t*>(myData.ValueXYZ(theX, theY, theZ)); 0417 } 0418 0419 //! Access image pixel with specified color type. 0420 //! Indexation starts from 0. 0421 //! This method does not perform any type checks - use on own risk (check Format() before)! 0422 //! WARNING: Input parameters are defined in traditional X, Y, Z order. 0423 template <typename ColorType_t> 0424 ColorType_t& ChangeValueXYZ(size_t theX, size_t theY, size_t theZ) 0425 { 0426 return *reinterpret_cast<ColorType_t*>(myData.ChangeValueXYZ(theX, theY, theZ)); 0427 } 0428 0429 //! Access image pixel as raw data pointer. 0430 //! Indexation starts from 0. 0431 //! This method does not perform any type checks - use on own risk (check Format() before)! 0432 //! WARNING: Input parameters are defined in traditional X, Y, Z order. 0433 const uint8_t* RawValueXYZ(size_t theX, size_t theY, size_t theZ) const 0434 { 0435 return myData.ValueXYZ(theX, theY, theZ); 0436 } 0437 0438 //! Access image pixel as raw data pointer. 0439 //! Indexation starts from 0. 0440 //! This method does not perform any type checks - use on own risk (check Format() before)! 0441 //! WARNING: Input parameters are defined in traditional X, Y, Z order. 0442 uint8_t* ChangeRawValueXYZ(size_t theX, size_t theY, size_t theZ) 0443 { 0444 return myData.ChangeValueXYZ(theX, theY, theZ); 0445 } 0446 0447 public: 0448 //! Convert 16-bit half-float value into 32-bit float (simple conversion). 0449 static float ConvertFromHalfFloat(const uint16_t theHalf) 0450 { 0451 union FloatUint32 { 0452 float Float32; 0453 uint32_t UInt32; 0454 }; 0455 0456 const uint32_t e = (theHalf & 0x7C00) >> 10; // exponent 0457 const uint32_t m = (theHalf & 0x03FF) << 13; // mantissa 0458 FloatUint32 mf, aRes; 0459 mf.Float32 = (float)m; 0460 // clang-format off 0461 const uint32_t v = mf.UInt32 >> 23; // evil log2 bit hack to count leading zeros in denormalized format 0462 aRes.UInt32 = (theHalf & 0x8000)<<16 | (e != 0) * ((e + 112) << 23 | m) | ((e == 0) & (m != 0)) * ((v - 37) << 23 | ((m << (150 - v)) & 0x007FE000)); // sign : normalized : denormalized 0463 // clang-format on 0464 return aRes.Float32; 0465 } 0466 0467 //! Convert 32-bit float value into IEEE-754 16-bit floating-point format without infinity: 0468 //! 1-5-10, exp-15, +-131008.0, +-6.1035156E-5, +-5.9604645E-8, 3.311 digits. 0469 static uint16_t ConvertToHalfFloat(const float theFloat) 0470 { 0471 union FloatUint32 { 0472 float Float32; 0473 uint32_t UInt32; 0474 }; 0475 0476 FloatUint32 anInput; 0477 anInput.Float32 = theFloat; 0478 // clang-format off 0479 const uint32_t b = anInput.UInt32 + 0x00001000; // round-to-nearest-even: add last bit after truncated mantissa 0480 const uint32_t e = (b & 0x7F800000) >> 23; // exponent 0481 const uint32_t m = b & 0x007FFFFF; // mantissa; in line below: 0x007FF000 = 0x00800000-0x00001000 = decimal indicator flag - initial rounding 0482 return (uint16_t)((b & 0x80000000) >> 16 | (e > 112) * ((((e - 112) << 10) & 0x7C00) | m >> 13) 0483 | ((e < 113) & (e > 101)) * ((((0x007FF000 + m) >> (125 - e)) + 1) >> 1) | (e > 143) * 0x7FFF); // sign : normalized : denormalized : saturate 0484 // clang-format on 0485 } 0486 0487 protected: 0488 Image_PixMapData myData; //!< data buffer 0489 Image_Format myImgFormat; //!< pixel format 0490 0491 private: 0492 //! Copying allowed only within Handles 0493 Image_PixMap(const Image_PixMap&) = delete; 0494 Image_PixMap& operator=(const Image_PixMap&) = delete; 0495 }; 0496 0497 #endif // _Image_PixMap_H__
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|