// ____ ______ __ // / __ \ / ____// / // / /_/ // / / / // / ____// /___ / /___ PixInsight Class Library // /_/ \____//_____/ PCL 2.4.23 // ---------------------------------------------------------------------------- // pcl/ICCProfileTransformation.h - Released 2022-03-12T18:59:29Z // ---------------------------------------------------------------------------- // This file is part of the PixInsight Class Library (PCL). // PCL is a multiplatform C++ framework for development of PixInsight modules. // // Copyright (c) 2003-2022 Pleiades Astrophoto S.L. All Rights Reserved. // // Redistribution and use in both source and binary forms, with or without // modification, is permitted provided that the following conditions are met: // // 1. All redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // 2. All redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // 3. Neither the names "PixInsight" and "Pleiades Astrophoto", nor the names // of their contributors, may be used to endorse or promote products derived // from this software without specific prior written permission. For written // permission, please contact info@pixinsight.com. // // 4. All products derived from this software, in any form whatsoever, must // reproduce the following acknowledgment in the end-user documentation // and/or other materials provided with the product: // // "This product is based on software from the PixInsight project, developed // by Pleiades Astrophoto and its contributors (https://pixinsight.com/)." // // Alternatively, if that is where third-party acknowledgments normally // appear, this acknowledgment must be reproduced in the product itself. // // THIS SOFTWARE IS PROVIDED BY PLEIADES ASTROPHOTO AND ITS CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PLEIADES ASTROPHOTO OR ITS // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, BUSINESS // INTERRUPTION; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; AND LOSS OF USE, // DATA OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // ---------------------------------------------------------------------------- #ifndef __PCL_ICCProfileTransformation_h #define __PCL_ICCProfileTransformation_h /// \file pcl/ICCProfileTransformation.h #include #include #include #include #include #include // ---------------------------------------------------------------------------- #ifdef __PCL_BUILDING_PIXINSIGHT_APPLICATION namespace pi { class ImageWindow; } // pi #endif namespace pcl { // ---------------------------------------------------------------------------- /*! * \class ICCProfileTransformation * \brief Conversion of pixel values between ICC profile color spaces * * %ICCProfileTransformation is a portable color transformation based on ICC * color profiles. This class is a high-level interface to the color management * functionality implemented in the PixInsight core application. * * %ICCProfileTransformation implements simple profile-to-profile color * transformations, multiprofile transformations, and device proofing * transformations with out-of-gamut checks. * * \ingroup color_management * \sa ICCProfile, ImageTransformation */ class PCL_CLASS ICCProfileTransformation : public ImageTransformation, public ParallelProcess { public: /*! * Represents an ICC rendering intent. */ typedef ICCRenderingIntent::value_type rendering_intent; /*! * Represents an opaque handle to a server-side ICC transformation. */ typedef void* transformation_handle; /*! * Represents a list of handles to open ICC profiles. */ typedef Array profile_list; /*! * Constructs an empty %ICCPRofileTransformation object. */ ICCProfileTransformation() = default; /*! * Move constructor. */ ICCProfileTransformation( ICCProfileTransformation&& x ) : ImageTransformation( x ) , ParallelProcess( x ) , m_transformation( x.m_transformation ) , m_profiles( std::move( x.m_profiles ) ) , m_intent( x.m_intent ) , m_proofingIntent( x.m_proofingIntent ) , m_blackPointCompensation( x.m_blackPointCompensation ) , m_forceFloatingPoint( x.m_forceFloatingPoint ) , m_highResolutionCLUT( x.m_highResolutionCLUT ) , m_lowResolutionCLUT( x.m_lowResolutionCLUT ) , m_proofingTransformation( x.m_proofingTransformation ) , m_gamutCheck( x.m_gamutCheck ) , m_srcRGB( x.m_srcRGB ) , m_dstRGB( x.m_dstRGB ) , m_floatingPoint( x.m_floatingPoint ) { x.m_transformation = nullptr; } /*! * Move assignment operator. Returns a reference to this object. */ ICCProfileTransformation& operator =( ICCProfileTransformation&& x ) { (void)ImageTransformation::operator =( x ); (void)ParallelProcess::operator =( x ); m_transformation = x.m_transformation; m_profiles = std::move( x.m_profiles ); m_intent = x.m_intent; m_proofingIntent = x.m_proofingIntent; m_blackPointCompensation = x.m_blackPointCompensation; m_forceFloatingPoint = x.m_forceFloatingPoint; m_highResolutionCLUT = x.m_highResolutionCLUT; m_lowResolutionCLUT = x.m_lowResolutionCLUT; m_proofingTransformation = x.m_proofingTransformation; m_gamutCheck = x.m_gamutCheck; m_srcRGB = x.m_srcRGB; m_dstRGB = x.m_dstRGB; m_floatingPoint = x.m_floatingPoint; x.m_transformation = nullptr; return *this; } /*! * Copy constructor. This constructor is disabled because ICC color profile * transformations are unique objects. */ ICCProfileTransformation( const ICCProfileTransformation& ) = delete; /*! * Copy assignment. This operator is disabled because ICC color profile * transformations are unique objects. */ ICCProfileTransformation& operator =( const ICCProfileTransformation& ) = delete; /*! * Destroys an %ICCPRofileTransformation object. */ virtual ~ICCProfileTransformation() { Clear(); } /*! * Loads an ICC profile from a file at \a profilePath and adds it to this * ICC profile transformation. */ void Add( const String& profilePath ); /*! * Adds the specified ICC \a profile to this ICC profile transformation. */ void Add( const ICCProfile& profile ); /*! * Adds an already open ICC profile \a profileHandle to this ICC profile * transformation. */ void Add( const ICCProfile::handle profileHandle ); /*! * Returns true iff this object represents a valid color space transformation * based on ICC color profiles. * * For this member function to return true, the underlying low-level * transformation should have been created, either implicitly by using * this object to apply a color transformation, or explicitly by calling * Create(). */ bool IsValid() const { return m_transformation != nullptr; } /*! * Returns a reference to the immutable list of ICC profiles in this ICC * profile transformation. */ const profile_list& Profiles() const { return m_profiles; } /*! * Returns the ICC rendering intent for this ICC profile transformation. */ rendering_intent RenderingIntent() const { return m_intent; } /*! * Sets the ICC rendering intent for this ICC profile transformation. * * When no intent is set explicitly with this function, the default * rendering intent is ICCRenderingIntent::Perceptual. */ void SetRenderingIntent( rendering_intent i ) { CloseTransformation(); m_intent = i; } /*! * Returns true iff this ICC profile transformation applies a black point * compensation algorithm. */ bool UsingBlackPointCompensation() const { return m_blackPointCompensation; } /*! * Enables or disables black point compensation for this ICC * profile transformation. * * When not enabled explicitly with this function, no black point * compensation is applied by default. */ void EnableBlackPointCompensation( bool enable = true ) { CloseTransformation(); m_blackPointCompensation = enable; } /*! * Disables or enables black point compensation for this ICC * profile transformation. * * This is a convenience member function, equivalent to * EnableBlackPointCompensation( !disable ) */ void DisableBlackPointCompensation( bool disable = true ) { EnableBlackPointCompensation( !disable ); } /*! * Returns true iff this ICC profile transformation forces the use of * floating point operations for computation of transformed pixel samples of * all numerical data types. * * When this option is disabled (which is its default state), 16-bit integer * arithmetics will be used for 8-bit and 16-bit integer images. Floating * point will always be used for the rest of images, irrespective of the * state of this option, in order to preserve numerical accuracy. */ bool ForcesFloatingPointTransformation() const { return m_forceFloatingPoint; } /*! * Enables or disables enforcement of floating point computations for this * ICC profile transformation. */ void ForceFloatingPointTransformation( bool force = true ) { CloseTransformation(); m_forceFloatingPoint = force; } /*! * Disables or enables enforcement of floating point computations for this * ICC profile transformation. * * This is a convenience member function, equivalent to * ForceFloatingPointTransformation( !relax ) */ void RelaxFloatingPointTransformation( bool relax = true ) { ForceFloatingPointTransformation( !relax ); } /*! * Returns true iff this ICC profile transformation uses high-resolution * color lookup tables (CLUTs) for precalculation of device link functions. * * Disabling high-resolution CLUTs may provide a (usually small) speed * improvement. * * By default, %ICCProfileTransformation uses high-resolution CLUTs. */ bool UsingHighResolutionCLUT() const { return m_highResolutionCLUT; } /*! * Enables or disables usage of high-resolution CLUT tables for this ICC * profile transformation. */ void EnableHighResolutionCLUT( bool enable = true ) { CloseTransformation(); if ( (m_highResolutionCLUT = enable) == true ) m_lowResolutionCLUT = false; } /*! * Disables or enables usage of high-resolution CLUT tables for this ICC * profile transformation. * * This is a convenience member function, equivalent to * EnableHighResolutionCLUT( !disable ) */ void DisableHighResolutionCLUT( bool disable = true ) { EnableHighResolutionCLUT( !disable ); } /*! * Returns true iff this ICC profile transformation uses low-resolution color * lookup tables (CLUTs) for precalculation of device link functions. * * Enabling low-resolution CLUTs may provide a (usually small) speed * improvement. * * By default, %ICCProfileTransformation uses high-resolution CLUTs. */ bool UsingLowResolutionCLUT() const { return m_lowResolutionCLUT; } /*! * Enables or disables usage of low-resolution color lookup tables (CLUTs) * in this ICC color transformation. */ void EnableLowResolutionCLUT( bool enable = true ) { CloseTransformation(); if ( (m_lowResolutionCLUT = enable) == true ) m_highResolutionCLUT = false; } /*! * Disables or enables usage of low-resolution color lookup tables (CLUTs) * in this ICC color transformation. * * This is a convenience member function, equivalent to * EnableLowResolutionCLUT( !disable ) */ void DisableLowResolutionCLUT( bool disable = true ) { EnableLowResolutionCLUT( !disable ); } /*! * Returns true iff this object represents a device proofing transformation. */ bool IsProofingTransformation() const { return m_proofingTransformation; } /*! * Forces the immediate creation (or re-creation) of the underlying * low-level transformation. * * You normally shouldn't need to call this member function, since * %ICCProfileTransformation automatically creates the necessary low-level * transformations at the points they are required. */ void Create() { CreateTransformation( m_forceFloatingPoint ); } /*! * \internal * Returns the low-level handle that this %ICCProfileTransformation object * serves as a high-level interface to. * * This function is intended for private use of the PixInsight core * application; you normally shouldn't need to call it. */ transformation_handle Handle() const { return m_transformation; } /*! * Resets this %ICCProfileTransformation object to a default state. * * The list of ICC profiles is cleared and the underlying transformation and * all associated data structures are destroyed. */ void Clear(); /*! * Returns true iff the starting ICC profile in this transformation is a RGB * profile. */ bool IsSourceRGBProfile() const { return m_srcRGB; } /*! * Returns true iff the target (last) ICC profile in this transformation is a * RGB profile. */ bool IsTargetRGBProfile() const { return m_dstRGB; } protected: /* * Opaque handle to the profile transformation. */ mutable transformation_handle m_transformation = nullptr; /* * The ICC profiles, rendering intents and operating parameters that define * this color transformation. */ profile_list m_profiles; rendering_intent m_intent = ICCRenderingIntent::Perceptual; rendering_intent m_proofingIntent = ICCRenderingIntent::AbsoluteColorimetric; bool m_blackPointCompensation = false; bool m_forceFloatingPoint = false; bool m_highResolutionCLUT = true; bool m_lowResolutionCLUT = false; bool m_proofingTransformation = false; bool m_gamutCheck = false; /* * Flags indicating source and destination color spaces. * ### NB: These refer to the color spaces of the source and target pixel * buffers, *not* to the color spaces of the profiles involved in the * transformation. */ mutable bool m_srcRGB = false; mutable bool m_dstRGB = false; /* * Flag indicating whether the current transformation (if any) has been * created forcing floating point arithmetics. */ mutable bool m_floatingPoint = false; void AddAt( size_type, const String& ); void AddAt( size_type, const ICCProfile& ); void AddAt( size_type, const ICCProfile::handle ); void AddOrReplaceAt( size_type i, const ICCProfile::handle ); void CreateTransformation( bool ) const; void CloseTransformation() const; // Inherited from ImageTransformation void Apply( pcl::Image& ) const override; void Apply( pcl::DImage& ) const override; void Apply( pcl::UInt8Image& ) const override; void Apply( pcl::UInt16Image& ) const override; void Apply( pcl::UInt32Image& ) const override; }; // ---------------------------------------------------------------------------- /*! * \class ICCProofingTransformation * \brief A soft proofing ICC profile transformation * * %ICCProofingTransformation implements a device proofing * transformation. This kind of color transformation allows previewing of * the final results that would be obtained on a specific proofing * device without actually performing any rendition on physical media. * * A device proofing transformation uses three ICC profiles: a source * profile, a proofing profile, and a target profile. In * a typical scenario, the proofing device is a printer and we want to proof it * on a display monitor. In this common case we have: * * Source profile = The ICC profile describing the color space to which source * pixel values are referred. * * Proofing profile = The ICC profile describing the device where the final * result will be obtained (usually a printer). * * Target profile = The ICC profile describing the display device where we'll * preview the result (usually a monitor). * * \ingroup color_management * \sa ICCProfileTransformation, ICCProfile */ class PCL_CLASS ICCProofingTransformation : public ICCProfileTransformation { public: /*! * Constructs a default %ICCProofingTransformation object. */ ICCProofingTransformation() { m_proofingTransformation = true; m_profiles.Add( static_cast( nullptr ), 3 ); } /*! * Move constructor. */ ICCProofingTransformation( ICCProofingTransformation&& ) = default; /*! * Destroys an %ICCProofingTransformation object. */ virtual ~ICCProofingTransformation() { } /*! * Move assignment operator. Returns a reference to this object. */ ICCProofingTransformation& operator =( ICCProofingTransformation&& ) = default; /*! * Loads an ICC profile from a file at \a profilePath and selects it as the * profile describing the source color space in this transformation. */ void SetSourceProfile( const String& profilePath ); /*! * Selects the specified ICC \a profile as the profile describing the source * color space in this transformation. */ void SetSourceProfile( const ICCProfile& profile ); /*! * Selects an already open ICC profile \a profileHandle as the profile * describing the source color space in this transformation. */ void SetSourceProfile( const ICCProfile::handle profileHandle ); /*! * Loads an ICC profile from a file at \a profilePath and selects it as the * profile describing the proofing device in this transformation. */ void SetProofingProfile( const String& profilePath ); /*! * Selects the specified ICC \a profile as the profile describing the * proofing device in this transformation. */ void SetProofingProfile( const ICCProfile& profile ); /*! * Selects an already open ICC profile \a profileHandle as the profile * describing the proofing device in this transformation. */ void SetProofingProfile( const ICCProfile::handle profileHandle ); /*! * Loads an ICC profile from a file at \a profilePath and selects it as the * profile describing the target (output) color space in this * transformation. */ void SetTargetProfile( const String& profilePath ); /*! * Selects the specified ICC \a profile as the profile describing the target * (output) color space in this transformation. */ void SetTargetProfile( const ICCProfile& profile ); /*! * Selects an already open ICC profile \a profileHandle as the profile * describing the target (output) color space in this transformation. */ void SetTargetProfile( const ICCProfile::handle profileHandle ); /*! * Returns the proofing rendering intent for this ICC proofing * transformation. */ rendering_intent ProofingIntent() const { return m_intent; } /*! * Sets the proofing rendering intent for this ICC proofing transformation. * * The default proofing intent is ICCRenderingIntent::AbsoluteColorimetric. */ void SetProofingIntent( rendering_intent i ) { CloseTransformation(); m_proofingIntent = i; } /*! * Returns true iff gamut checking has been enabled for this color * transformation. When gamut check is enabled, out-of-gamut colors in the * final rendition are automatically replaced by the current gamut * warning color (see the SetGamutWarningColor() member function). */ bool IsGamutCheckEnabled() const { return m_gamutCheck; } /*! * Enables or disables gamut check for this color transformation. */ void EnableGamutCheck( bool enable = true ) { CloseTransformation(); m_gamutCheck = enable; } /*! * Disables or enables gamut check for this color transformation. */ void DisableGamutCheck( bool disable = true ) { EnableGamutCheck( !disable ); } /*! * Returns the current gamut warning color used to represent * out-of-gamut pixel values in final proofing renditions. The returned * value is a 32-bit RGBA pixel value. */ static RGBA GamutWarningColor(); /*! * Specifies the special RGB color used to represent out-of-gamut pixel * values in final proofing renditions. Only used for proofing * transformations with gamut check enabled. * * \param color Gamut warning color encoded as a 32-bit RGBA pixel value. * * Note that since this is a static member function, the current gamut * warning color is a global setting that affects all proofing * transformations performed by the calling module. */ static void SetGamutWarningColor( RGBA color ); }; // ---------------------------------------------------------------------------- } // pcl #endif // __PCL_ICCProfileTransformation_h // ---------------------------------------------------------------------------- // EOF pcl/ICCProfileTransformation.h - Released 2022-03-12T18:59:29Z