Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:04:41

0001 // Created by: NW,JPB,CAL
0002 // Copyright (c) 1991-1999 Matra Datavision
0003 // Copyright (c) 1999-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 _Quantity_Color_HeaderFile
0017 #define _Quantity_Color_HeaderFile
0018 
0019 #include <Standard.hxx>
0020 #include <Standard_DefineAlloc.hxx>
0021 #include <Standard_Handle.hxx>
0022 #include <Standard_HashUtils.hxx>
0023 #include <Standard_ShortReal.hxx>
0024 
0025 #include <Quantity_NameOfColor.hxx>
0026 #include <Quantity_TypeOfColor.hxx>
0027 #include <NCollection_Vec4.hxx>
0028 
0029 //! This class allows the definition of an RGB color as triplet of 3 normalized floating point values (red, green, blue).
0030 //!
0031 //! Although Quantity_Color can be technically used for pass-through storage of RGB triplet in any color space,
0032 //! other OCCT interfaces taking/returning Quantity_Color would expect them in linear space.
0033 //! Therefore, take a look into methods converting to and from non-linear sRGB color space, if needed;
0034 //! for instance, application usually providing color picking within 0..255 range in sRGB color space.
0035 class Quantity_Color
0036 {
0037 public:
0038 
0039   DEFINE_STANDARD_ALLOC
0040 
0041   //! Creates Quantity_NOC_YELLOW color (for historical reasons).
0042   Quantity_Color() : myRgb (valuesOf (Quantity_NOC_YELLOW, Quantity_TOC_RGB)) {}
0043 
0044   //! Creates the color from enumeration value.
0045   Quantity_Color (const Quantity_NameOfColor theName) : myRgb (valuesOf (theName, Quantity_TOC_RGB)) {}
0046 
0047   //! Creates a color according to the definition system theType.
0048   //! Throws exception if values are out of range.
0049   Standard_EXPORT Quantity_Color (const Standard_Real theC1,
0050                                   const Standard_Real theC2,
0051                                   const Standard_Real theC3,
0052                                   const Quantity_TypeOfColor theType);
0053 
0054   //! Define color from linear RGB values.
0055   Standard_EXPORT explicit Quantity_Color (const NCollection_Vec3<float>& theRgb);
0056 
0057   //! Returns the name of the nearest color from the Quantity_NameOfColor enumeration.
0058   Standard_EXPORT Quantity_NameOfColor Name() const;
0059 
0060   //! Updates the color from specified named color.
0061   void SetValues (const Quantity_NameOfColor theName) { myRgb = valuesOf (theName, Quantity_TOC_RGB); }
0062 
0063   //! Return the color as vector of 3 float elements.
0064   const NCollection_Vec3<float>& Rgb () const { return myRgb; }
0065 
0066   //! Return the color as vector of 3 float elements.
0067   operator const NCollection_Vec3<float>&() const { return myRgb; }
0068 
0069   //! Returns in theC1, theC2 and theC3 the components of this color
0070   //! according to the color system definition theType.
0071   Standard_EXPORT void Values (Standard_Real& theC1,
0072                                Standard_Real& theC2,
0073                                Standard_Real& theC3,
0074                                const Quantity_TypeOfColor theType) const;
0075 
0076   //! Updates a color according to the mode specified by theType.
0077   //! Throws exception if values are out of range.
0078   Standard_EXPORT void SetValues (const Standard_Real theC1,
0079                                   const Standard_Real theC2,
0080                                   const Standard_Real theC3,
0081                                   const Quantity_TypeOfColor theType);
0082 
0083   //! Returns the Red component (quantity of red) of the color within range [0.0; 1.0].
0084   Standard_Real Red() const { return myRgb.r(); }
0085 
0086   //! Returns the Green component (quantity of green) of the color within range [0.0; 1.0].
0087   Standard_Real Green() const { return myRgb.g(); }
0088 
0089   //! Returns the Blue component (quantity of blue) of the color within range [0.0; 1.0].
0090   Standard_Real Blue() const { return myRgb.b(); }
0091 
0092   //! Returns the Hue component (hue angle) of the color
0093   //! in degrees within range [0.0; 360.0], 0.0 being Red.
0094   //! -1.0 is a special value reserved for grayscale color (S should be 0.0)
0095   Standard_Real Hue() const { return Convert_LinearRGB_To_HLS (myRgb)[0]; }
0096 
0097   //! Returns the Light component (value of the lightness) of the color within range [0.0; 1.0].
0098   Standard_Real Light() const { return Convert_LinearRGB_To_HLS (myRgb)[1]; }
0099 
0100   //! Increases or decreases the intensity (variation of the lightness).
0101   //! The delta is a percentage. Any value greater than zero will increase the intensity.
0102   //! The variation is expressed as a percentage of the current value.
0103   Standard_EXPORT void ChangeIntensity (const Standard_Real theDelta);
0104 
0105   //! Returns the Saturation component (value of the saturation) of the color within range [0.0; 1.0].
0106   Standard_Real Saturation() const { return Convert_LinearRGB_To_HLS (myRgb)[2]; }
0107 
0108   //! Increases or decreases the contrast (variation of the saturation).
0109   //! The delta is a percentage. Any value greater than zero will increase the contrast.
0110   //! The variation is expressed as a percentage of the current value.
0111   Standard_EXPORT void ChangeContrast (const Standard_Real theDelta);
0112 
0113   //! Returns TRUE if the distance between two colors is greater than Epsilon().
0114   Standard_Boolean IsDifferent (const Quantity_Color& theOther) const { return (SquareDistance (theOther) > Epsilon() * Epsilon()); }
0115 
0116   //! Alias to IsDifferent().
0117   Standard_Boolean operator!=  (const Quantity_Color& theOther) const { return IsDifferent (theOther); }
0118 
0119   //! Returns TRUE if the distance between two colors is no greater than Epsilon().
0120   Standard_Boolean IsEqual    (const Quantity_Color& theOther) const { return (SquareDistance (theOther) <= Epsilon() * Epsilon()); }
0121 
0122   //! Alias to IsEqual().
0123   Standard_Boolean operator== (const Quantity_Color& theOther) const { return IsEqual (theOther); }
0124   
0125   //! Returns the distance between two colors. It's a value between 0 and the square root of 3 (the black/white distance).
0126   Standard_Real Distance (const Quantity_Color& theColor) const
0127   {
0128     return (NCollection_Vec3<Standard_Real> (myRgb) - NCollection_Vec3<Standard_Real> (theColor.myRgb)).Modulus();
0129   }
0130 
0131   //! Returns the square of distance between two colors.
0132   Standard_Real SquareDistance (const Quantity_Color& theColor) const
0133   {
0134     return (NCollection_Vec3<Standard_Real> (myRgb) - NCollection_Vec3<Standard_Real> (theColor.myRgb)).SquareModulus();
0135   }
0136 
0137   //! Returns the percentage change of contrast and intensity between this and another color.
0138   //! <DC> and <DI> are percentages, either positive or negative.
0139   //! The calculation is with respect to this color.
0140   //! If <DC> is positive then <me> is more contrasty.
0141   //! If <DI> is positive then <me> is more intense.
0142   Standard_EXPORT void Delta (const Quantity_Color& theColor,
0143                               Standard_Real& DC, Standard_Real& DI) const;
0144 
0145   //! Returns the value of the perceptual difference between this color
0146   //! and @p theOther, computed using the CIEDE2000 formula.
0147   //! The difference is in range [0, 100.], with 1 approximately corresponding
0148   //! to the minimal percievable difference (usually difference 5 or greater is
0149   //! needed for the difference to be recognizable in practice).
0150   Standard_EXPORT Standard_Real DeltaE2000 (const Quantity_Color& theOther) const;
0151 
0152 public:
0153 
0154   //! Returns the color from Quantity_NameOfColor enumeration nearest to specified RGB values.
0155   static Quantity_NameOfColor Name (const Standard_Real theR, const Standard_Real theG, const Standard_Real theB)
0156   {
0157     const Quantity_Color aColor (theR, theG, theB, Quantity_TOC_RGB);
0158     return aColor.Name();
0159   }
0160 
0161   //! Returns the name of the color identified by the given Quantity_NameOfColor enumeration value.
0162   Standard_EXPORT static Standard_CString StringName (const Quantity_NameOfColor theColor);
0163 
0164   //! Finds color from predefined names.
0165   //! For example, the name of the color which corresponds to "BLACK" is Quantity_NOC_BLACK.
0166   //! Returns FALSE if name is unknown.
0167   Standard_EXPORT static Standard_Boolean ColorFromName (const Standard_CString theName, Quantity_NameOfColor& theColor);
0168 
0169   //! Finds color from predefined names.
0170   //! @param theColorNameString the color name
0171   //! @param theColor a found color
0172   //! @return false if the color name is unknown, or true if the search by color name was successful
0173   static Standard_Boolean ColorFromName (const Standard_CString theColorNameString, Quantity_Color& theColor)
0174   {
0175     Quantity_NameOfColor aColorName = Quantity_NOC_BLACK;
0176     if (!ColorFromName (theColorNameString, aColorName))
0177     {
0178       return false;
0179     }
0180     theColor = aColorName;
0181     return true;
0182   }
0183 
0184 public:
0185   //!@name Routines converting colors between different encodings and color spaces
0186 
0187   //! Parses the string as a hex color (like "#FF0" for short sRGB color, or "#FFFF00" for sRGB color)
0188   //! @param theHexColorString the string to be parsed
0189   //! @param theColor a color that is a result of parsing
0190   //! @return true if parsing was successful, or false otherwise
0191   Standard_EXPORT static bool ColorFromHex (const Standard_CString theHexColorString, Quantity_Color& theColor);
0192 
0193   //! Returns hex sRGB string in format "#FFAAFF".
0194   static TCollection_AsciiString ColorToHex (const Quantity_Color& theColor,
0195                                              const bool theToPrefixHash = true)
0196   {
0197     NCollection_Vec3<Standard_ShortReal> anSRgb = Convert_LinearRGB_To_sRGB ((NCollection_Vec3<Standard_ShortReal> )theColor);
0198     NCollection_Vec3<Standard_Integer> anSRgbInt (anSRgb * 255.0f + NCollection_Vec3<Standard_ShortReal> (0.5f));
0199     char aBuff[10];
0200     Sprintf (aBuff, theToPrefixHash ? "#%02X%02X%02X" : "%02X%02X%02X",
0201              anSRgbInt.r(), anSRgbInt.g(), anSRgbInt.b());
0202     return aBuff;
0203   }
0204 
0205   //! Converts sRGB components into HLS ones.
0206   Standard_EXPORT static NCollection_Vec3<float> Convert_sRGB_To_HLS (const NCollection_Vec3<float>& theRgb);
0207 
0208   //! Converts HLS components into RGB ones.
0209   Standard_EXPORT static NCollection_Vec3<float> Convert_HLS_To_sRGB (const NCollection_Vec3<float>& theHls);
0210 
0211   //! Converts Linear RGB components into HLS ones.
0212   static NCollection_Vec3<float> Convert_LinearRGB_To_HLS (const NCollection_Vec3<float>& theRgb)
0213   {
0214     return Convert_sRGB_To_HLS (Convert_LinearRGB_To_sRGB (theRgb));
0215   }
0216 
0217   //! Converts HLS components into linear RGB ones.
0218   static NCollection_Vec3<float> Convert_HLS_To_LinearRGB (const NCollection_Vec3<float>& theHls)
0219   {
0220     return Convert_sRGB_To_LinearRGB (Convert_HLS_To_sRGB (theHls));
0221   }
0222 
0223   //! Converts linear RGB components into CIE Lab ones.
0224   Standard_EXPORT static NCollection_Vec3<float> Convert_LinearRGB_To_Lab (const NCollection_Vec3<float>& theRgb);
0225 
0226   //! Converts CIE Lab components into CIE Lch ones.
0227   Standard_EXPORT static NCollection_Vec3<float> Convert_Lab_To_Lch (const NCollection_Vec3<float>& theLab);
0228 
0229   //! Converts CIE Lab components into linear RGB ones.
0230   //! Note that the resulting values may be out of the valid range for RGB.
0231   Standard_EXPORT static NCollection_Vec3<float> Convert_Lab_To_LinearRGB (const NCollection_Vec3<float>& theLab);
0232 
0233   //! Converts CIE Lch components into CIE Lab ones.
0234   Standard_EXPORT static NCollection_Vec3<float> Convert_Lch_To_Lab (const NCollection_Vec3<float>& theLch);
0235 
0236   //! Convert the color value to ARGB integer value, with alpha equals to 0.
0237   //! So the output is formatted as 0x00RRGGBB.
0238   //! Note that this unpacking does NOT involve non-linear sRGB -> linear RGB conversion,
0239   //! as would be usually expected for RGB color packed into 4 bytes.
0240   //! @param theColor [in] color to convert
0241   //! @param theARGB [out] result color encoded as integer
0242   static void Color2argb (const Quantity_Color& theColor,
0243                           Standard_Integer& theARGB)
0244   {
0245     const NCollection_Vec3<Standard_Integer> aColor (static_cast<Standard_Integer> (255.0f * theColor.myRgb.r() + 0.5f),
0246                                                      static_cast<Standard_Integer> (255.0f * theColor.myRgb.g() + 0.5f),
0247                                                      static_cast<Standard_Integer> (255.0f * theColor.myRgb.b() + 0.5f));
0248     theARGB = (((aColor.r() & 0xff) << 16)
0249              | ((aColor.g() & 0xff) << 8)
0250              |  (aColor.b() & 0xff));
0251   }
0252 
0253   //! Convert integer ARGB value to Color. Alpha bits are ignored.
0254   //! Note that this packing does NOT involve linear -> non-linear sRGB conversion,
0255   //! as would be usually expected to preserve higher (for human eye) color precision in 4 bytes.
0256   static void Argb2color (const Standard_Integer theARGB,
0257                           Quantity_Color& theColor)
0258   {
0259     const NCollection_Vec3<Standard_Real> aColor (static_cast <Standard_Real> ((theARGB & 0xff0000) >> 16),
0260                                                   static_cast <Standard_Real> ((theARGB & 0x00ff00) >> 8),
0261                                                   static_cast <Standard_Real> ((theARGB & 0x0000ff)));
0262     theColor.SetValues (aColor.r() / 255.0, aColor.g() / 255.0, aColor.b() / 255.0, Quantity_TOC_sRGB);
0263   }
0264 
0265   //! Convert linear RGB component into sRGB using OpenGL specs formula (double precision), also known as gamma correction.
0266   static Standard_Real Convert_LinearRGB_To_sRGB (Standard_Real theLinearValue)
0267   {
0268     return theLinearValue <= 0.0031308
0269          ? theLinearValue * 12.92
0270          : Pow (theLinearValue, 1.0/2.4) * 1.055 - 0.055;
0271   }
0272 
0273   //! Convert linear RGB component into sRGB using OpenGL specs formula (single precision), also known as gamma correction.
0274   static float Convert_LinearRGB_To_sRGB (float theLinearValue)
0275   {
0276     return theLinearValue <= 0.0031308f
0277          ? theLinearValue * 12.92f
0278          : powf (theLinearValue, 1.0f/2.4f) * 1.055f - 0.055f;
0279   }
0280 
0281   //! Convert sRGB component into linear RGB using OpenGL specs formula (double precision), also known as gamma correction.
0282   static Standard_Real Convert_sRGB_To_LinearRGB (Standard_Real thesRGBValue)
0283   {
0284     return thesRGBValue <= 0.04045
0285          ? thesRGBValue / 12.92
0286          : Pow ((thesRGBValue + 0.055) / 1.055, 2.4);
0287   }
0288 
0289   //! Convert sRGB component into linear RGB using OpenGL specs formula (single precision), also known as gamma correction.
0290   static float Convert_sRGB_To_LinearRGB (float thesRGBValue)
0291   {
0292     return thesRGBValue <= 0.04045f
0293          ? thesRGBValue / 12.92f
0294          : powf ((thesRGBValue + 0.055f) / 1.055f, 2.4f);
0295   }
0296 
0297   //! Convert linear RGB components into sRGB using OpenGL specs formula.
0298   template<typename T>
0299   static NCollection_Vec3<T> Convert_LinearRGB_To_sRGB (const NCollection_Vec3<T>& theRGB)
0300   {
0301     return NCollection_Vec3<T> (Convert_LinearRGB_To_sRGB (theRGB.r()),
0302                                 Convert_LinearRGB_To_sRGB (theRGB.g()),
0303                                 Convert_LinearRGB_To_sRGB (theRGB.b()));
0304   }
0305 
0306   //! Convert sRGB components into linear RGB using OpenGL specs formula.
0307   template<typename T>
0308   static NCollection_Vec3<T> Convert_sRGB_To_LinearRGB (const NCollection_Vec3<T>& theRGB)
0309   {
0310     return NCollection_Vec3<T> (Convert_sRGB_To_LinearRGB (theRGB.r()),
0311                                 Convert_sRGB_To_LinearRGB (theRGB.g()),
0312                                 Convert_sRGB_To_LinearRGB (theRGB.b()));
0313   }
0314 
0315   //! Convert linear RGB component into sRGB using approximated uniform gamma coefficient 2.2.
0316   static float Convert_LinearRGB_To_sRGB_approx22 (float theLinearValue) { return powf (theLinearValue, 2.2f); }
0317 
0318   //! Convert sRGB component into linear RGB using approximated uniform gamma coefficient 2.2
0319   static float Convert_sRGB_To_LinearRGB_approx22 (float thesRGBValue) { return powf (thesRGBValue, 1.0f/2.2f); }
0320 
0321   //! Convert linear RGB components into sRGB using approximated uniform gamma coefficient 2.2
0322   static NCollection_Vec3<float> Convert_LinearRGB_To_sRGB_approx22 (const NCollection_Vec3<float>& theRGB)
0323   {
0324     return NCollection_Vec3<float> (Convert_LinearRGB_To_sRGB_approx22 (theRGB.r()),
0325                                     Convert_LinearRGB_To_sRGB_approx22 (theRGB.g()),
0326                                     Convert_LinearRGB_To_sRGB_approx22 (theRGB.b()));
0327   }
0328 
0329   //! Convert sRGB components into linear RGB using approximated uniform gamma coefficient 2.2
0330   static NCollection_Vec3<float> Convert_sRGB_To_LinearRGB_approx22 (const NCollection_Vec3<float>& theRGB)
0331   {
0332     return NCollection_Vec3<float> (Convert_sRGB_To_LinearRGB_approx22 (theRGB.r()),
0333                                     Convert_sRGB_To_LinearRGB_approx22 (theRGB.g()),
0334                                     Convert_sRGB_To_LinearRGB_approx22 (theRGB.b()));
0335   }
0336 
0337   //! Converts HLS components into sRGB ones.
0338   static void HlsRgb (const Standard_Real theH, const Standard_Real theL, const Standard_Real theS,
0339                       Standard_Real& theR, Standard_Real& theG, Standard_Real& theB)
0340   {
0341     const NCollection_Vec3<float> anRgb = Convert_HLS_To_sRGB (NCollection_Vec3<float> ((float )theH, (float )theL, (float )theS));
0342     theR = anRgb[0];
0343     theG = anRgb[1];
0344     theB = anRgb[2];
0345   }
0346 
0347   //! Converts sRGB components into HLS ones.
0348   static void RgbHls (const Standard_Real theR, const Standard_Real theG, const Standard_Real theB,
0349                       Standard_Real& theH, Standard_Real& theL, Standard_Real& theS)
0350   {
0351     const NCollection_Vec3<float> aHls = Convert_sRGB_To_HLS (NCollection_Vec3<float> ((float )theR, (float )theG, (float )theB));
0352     theH = aHls[0];
0353     theL = aHls[1];
0354     theS = aHls[2];
0355   }
0356 
0357 public:
0358 
0359   //! Returns the value used to compare two colors for equality; 0.0001 by default.
0360   Standard_EXPORT static Standard_Real Epsilon();
0361 
0362   //! Set the value used to compare two colors for equality.
0363   Standard_EXPORT static void SetEpsilon (const Standard_Real theEpsilon);
0364 
0365   //! Dumps the content of me into the stream
0366   Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
0367 
0368   //! Inits the content of me from the stream
0369   Standard_EXPORT Standard_Boolean InitFromJson (const Standard_SStream& theSStream, Standard_Integer& theStreamPos);
0370 
0371 private:
0372 
0373   //! Returns the values of a predefined color according to the mode.
0374   Standard_EXPORT static NCollection_Vec3<float> valuesOf (const Quantity_NameOfColor theName,
0375                                                            const Quantity_TypeOfColor theType);
0376 
0377 private:
0378 
0379   NCollection_Vec3<float> myRgb;
0380 
0381 };
0382 
0383 namespace std
0384 {
0385   template <>
0386   struct hash<Quantity_Color>
0387   {
0388     std::size_t operator()(const Quantity_Color& theColor) const noexcept
0389     {
0390       unsigned char aByteArr[3] = { static_cast<unsigned char>(255 * theColor.Red()),
0391                                     static_cast<unsigned char>(255 * theColor.Green()),
0392                                     static_cast<unsigned char>(255 * theColor.Blue()) };
0393       return opencascade::hashBytes(aByteArr, sizeof(aByteArr));
0394     }
0395   };
0396 }
0397 
0398 #endif // _Quantity_Color_HeaderFile