Support for XISF

This commit is contained in:
2022-04-12 08:17:18 +02:00
parent e5cd25cc77
commit 0fb27266c7
278 changed files with 209068 additions and 7 deletions
+463
View File
@@ -0,0 +1,463 @@
// ____ ______ __
// / __ \ / ____// /
// / /_/ // / / /
// / ____// /___ / /___ PixInsight Class Library
// /_/ \____//_____/ PCL 2.4.23
// ----------------------------------------------------------------------------
// pcl/DisplayFunction.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_DisplayFunction_h
#define __PCL_DisplayFunction_h
/// \file pcl/DisplayFunction.h
#include <pcl/Defs.h>
#include <pcl/Diagnostics.h>
#include <pcl/HistogramTransformation.h>
#include <pcl/Vector.h>
namespace pcl
{
// ----------------------------------------------------------------------------
/*
* Default clipping increment in sigma units.
*/
#define __PCL_AUTOSTRETCH_DEFAULT_CLIP -2.80
/*
* Default target mean background in the [0,1] range.
*/
#define __PCL_AUTOSTRETCH_DEFAULT_TBGD 0.25
/*
* Whether to apply a single transformation to nominal RGB channels, or
* separate per-channel transformations.
*/
#define __PCL_AUTOSTRETCH_DEFAULT_LINK false
// ----------------------------------------------------------------------------
/*!
* \class DisplayFunction
* \brief Adaptive histogram transformations for image visualization.
*
* %DisplayFunction implements a set of histogram transformations for
* visualization of linear images.
*/
class PCL_CLASS DisplayFunction : public ImageTransformation
{
public:
/*!
* Default constructor. Constructs an identity display function.
*/
DisplayFunction()
: m_m( 4 ), m_s( 4 ), m_h( 4 ), m_l( 4 ), m_r( 4 )
{
Reset();
}
/*!
* Constructs a display function with the specified parameters.
*
* \param m Vector of midtones balance parameters.
* \param s Vector of shadows clipping point parameters.
* \param h Vector of highlights clipping point parameters.
* \param l Vector of shadows dynamic range expansion parameters.
* \param r Vector of highlights dynamic range expansion parameters.
*
* Each argument vector can have from zero to four components (additional
* vector components are ignored, and missing components are replaced with
* default identity transformation parameters). Vector indices 0, 1, 2 and 3
* correspond to the red/gray, green, blue and lightness components for
* histogram transformations.
*
* For detailed information on parameter values and valid ranges, see the
* HistogramTransformation class.
*/
template <class V>
DisplayFunction( const V& m, const V& s, const V& h, const V& l = V(), const V& r = V() )
: m_m( 4 ), m_s( 4 ), m_h( 4 ), m_l( 4 ), m_r( 4 )
{
Reset();
for ( int i = 0; i < 4 && i < int( m.Length() ); ++i ) m_m[i] = Range( double( m[i] ), 0.0, 1.0 );
for ( int i = 0; i < 4 && i < int( s.Length() ); ++i ) m_s[i] = Range( double( s[i] ), 0.0, 1.0 );
for ( int i = 0; i < 4 && i < int( h.Length() ); ++i ) m_h[i] = Range( double( h[i] ), 0.0, 1.0 );
for ( int i = 0; i < 4 && i < int( l.Length() ); ++i ) m_l[i] = Max( 0.0, double( l[i] ) );
for ( int i = 0; i < 4 && i < int( r.Length() ); ++i ) m_r[i] = Min( 1.0, double( r[i] ) );
for ( int i = 0; i < 4; ++i )
if ( m_h[i] < m_s[i] )
pcl::Swap( m_s[i], m_h[i] );
}
/*!
* Copy constructor.
*/
DisplayFunction( const DisplayFunction& ) = default;
/*!
* Move constructor.
*/
DisplayFunction( DisplayFunction&& ) = default;
/*!
* Copy assignment operator. Returns a reference to this object.
*/
DisplayFunction& operator =( const DisplayFunction& ) = default;
/*!
* Move assignment operator. Returns a reference to this object.
*/
DisplayFunction& operator =( DisplayFunction&& ) = default;
/*!
* Virtual destructor.
*/
virtual ~DisplayFunction()
{
}
/*!
* Array subscript operator. Returns an histogram transformation for the
* specified channel index \a i, which must be in the range [0,3].
*
* Channel indices 0, 1, 2 and 3 correspond to the red/gray, green, blue and
* lightness components, respectively. If an out-of-range channel index is
* specified, this operator returns an identity histogram transformation.
*/
HistogramTransformation operator []( int i ) const
{
PCL_PRECONDITION( 0 <= i && i < 4 )
PCL_CHECK( m_m.Length() == 4 && m_s.Length() == 4 && m_h.Length() == 4 && m_l.Length() == 4 && m_r.Length() == 4 )
if ( i >= 0 && i < 4 )
return HistogramTransformation( m_m[i], m_s[i], m_h[i], m_l[i], m_r[i] );
return HistogramTransformation();
}
/*!
* Returns a dynamic array of histogram transformations.
*
* The returned object contains four HistogramTransformation instances,
* where array indexes 0, 1, 2 and 3 correspond to the red/gray, green, blue
* and lightness components, respectively.
*/
Array<HistogramTransformation> HistogramTransformations() const
{
return Array<HistogramTransformation>() << operator[]( 0 )
<< operator[]( 1 )
<< operator[]( 2 )
<< operator[]( 3 );
}
/*!
* Gets a copy of all display function parameters in the specified vectors.
*
* \param[out] m Vector of midtones balance parameters.
* \param[out] s Vector of shadows clipping point parameters.
* \param[out] h Vector of highlights clipping point parameters.
* \param[out] l Vector of shadows dynamic range expansion parameters.
* \param[out] r Vector of highlights dynamic range expansion parameters.
*
* On output, each vector will have four components with the histogram
* transformation parameters for the red/gray, green, blue and lightness
* image components at vector indexes 0, 1, 2 and 3, respectively.
*/
template <class V>
void GetDisplayFunctionParameters( V& m, V& s, V& h, V& l, V& r ) const
{
m = m_m; s = m_s; h = m_h; l = m_l; r = m_r;
}
/*!
* Returns true only if this object defines an identity display function for
* the specified channel index \a i.
*
* An identity display function is a no-op: it does not alter the pixel data
* or properties of the target images to which it is applied.
*/
bool IsIdentityTransformation( int i ) const
{
PCL_PRECONDITION( 0 <= i && i < 4 )
PCL_CHECK( m_m.Length() == 4 && m_s.Length() == 4 && m_h.Length() == 4 && m_l.Length() == 4 && m_r.Length() == 4 )
return i >= 0 && i < 4 && m_m[i] == 0.5 && m_s[i] == 0 && m_h[i] == 1 && m_l[i] == 0 && m_r[i] == 1;
}
/*!
* Returns true iff this is an identity display function for the four
* image components (red/gray, green, blue and lightness).
*
* An identity display function is a no-op: it does not alter the pixel data
* or properties of the target images to which it is applied.
*/
bool IsIdentityTransformation() const
{
return IsIdentityTransformation( 0 )
&& IsIdentityTransformation( 1 )
&& IsIdentityTransformation( 2 )
&& IsIdentityTransformation( 3 );
}
/*!
* Returns the clipping point parameter of this transformation, in sigma
* units from the central value.
*/
double ClippingPoint() const
{
return m_clip;
}
/*!
* Sets the clipping point parameter of this transformation, in sigma units
* from the central value. The default clipping point is -2.8.
*/
void SetClippingPoint( double clip )
{
m_clip = clip;
}
/*!
* Returns the target background parameter of this transformation in the
* normalized [0,1] range.
*/
double TargetBackground() const
{
return m_tbkg;
}
/*
* Sets the target background parameter of this transformation in the
* normalized [0,1] range. The default target background is 0.25.
*/
void SetTargetBackground( double tbkg )
{
m_tbkg = Range( tbkg, 0.0, 1.0 );
}
/*!
* Returns true iff this transformation will compute a single adaptive
* histogram transformation for the nominal channels of an RGB color image.
* Returns false if adaptive per-channel transformations will be calculated
* separately.
*/
bool LinkedRGB() const
{
return m_link;
}
/*!
* Sets the 'linked RGB' parameter of this transformation. When this
* parameter is true, a single adaptive histogram transformation will be
* computed for the nominal channels of an RGB color image. When this
* parameter is false, separate adaptive transformations will be calculated
* for each channel.
*/
void SetLinkedRGB( bool link = true )
{
m_link = link;
}
/*!
* Computes adaptive display functions, also known as <em>auto-stretch
* functions</em>, based on statistical estimates of scale and location.
*
* \param sigma Vector of scale estimates. This is typically a vector of
* normalized MAD values (median absolute deviation from the
* median) or similar robust dispersion estimates.
*
* \param center Vector of location estimates. Typically the median is used
* as a robust estimator of central tendency.
*
* Both vectors must have one or three components, respectively for a
* monochrome (grayscale) or RGB color image. Avoid using non-robust
* statistical estimators such as the standard deviation or the mean, which
* can easily lead to completely wrong results.
*
* To obtain results coherent with other implementations, scale estimates
* should be normalized to be consistent with the standard deviation of a
* normal distribution. For example, if MAD values are used, they should be
* multiplied by 1.4826 before calling this function.
*/
template <class V>
void ComputeAutoStretch( const V& sigma, const V& center )
{
PCL_CHECK( m_m.Length() == 4 && m_s.Length() == 4 && m_h.Length() == 4 && m_l.Length() == 4 && m_r.Length() == 4 )
if ( sigma.IsEmpty() || center.IsEmpty() )
{
Reset();
return;
}
int n = (sigma.Length() < 3 || center.Length() < 3) ? 1 : 3;
if ( m_link )
{
/*
* Try to find out how many channels look like channels of an inverted
* image.
*
* We know a channel is inverted because the main histogram peak is
* located over the right-hand half of the histogram. Seems simplistic
* but this is consistent with most real-world images.
*/
int invertedChannels = 0;
for ( int i = 0; i < n; ++i )
if ( center[i] > 0.5 )
++invertedChannels;
double c = 0, m = 0;
if ( invertedChannels < n )
{
// Noninverted image
for ( int i = 0; i < n; ++i )
{
if ( 1 + sigma[i] != 1 )
c += center[i] + m_clip * sigma[i];
m += center[i];
}
m_s[0] = m_s[1] = m_s[2] = Range( c/n, 0.0, 1.0 );
m_m[0] = m_m[1] = m_m[2] = HistogramTransformation::MTF( m_tbkg, m/n - m_s[0] );
m_l[0] = m_l[1] = m_l[2] = 0.0;
m_h[0] = m_h[1] = m_h[2] = m_r[0] = m_r[1] = m_r[2] = 1.0;
}
else
{
// Inverted image
for ( int i = 0; i < n; ++i )
{
c += (1 + sigma[i] != 1) ? center[i] - m_clip * sigma[i] : 1.0;
m += center[i];
}
m_h[0] = m_h[1] = m_h[2] = Range( c/n, 0.0, 1.0 );
m_m[0] = m_m[1] = m_m[2] = HistogramTransformation::MTF( m_h[0] - m/n, m_tbkg );
m_s[0] = m_s[1] = m_s[2] = m_l[0] = m_l[1] = m_l[2] = 0.0;
m_r[0] = m_r[1] = m_r[2] = 1.0;
}
}
else
{
/*
* Unlinked RGB/K channnels: Compute automatic stretch functions for
* individual RGB/K channels separately.
*/
for ( int i = 0; i < n; ++i )
if ( center[i] < 0.5 )
{
// Noninverted channel
m_s[i] = (1 + sigma[i] != 1) ? Range( center[i] + m_clip * sigma[i], 0.0, 1.0 ) : 0.0;
m_m[i] = HistogramTransformation::MTF( m_tbkg, center[i] - m_s[i] );
m_l[i] = 0.0;
m_h[i] = m_r[i] = 1.0;
}
else
{
// Inverted channel
m_h[i] = (1 + sigma[i] != 1) ? Range( center[i] - m_clip * sigma[i], 0.0, 1.0 ) : 1.0;
m_m[i] = HistogramTransformation::MTF( m_h[i] - center[i], m_tbkg );
m_s[i] = m_l[i] = 0.0;
m_r[i] = 1.0;
}
}
}
/*!
* Resets all display function parameters to yield an identity
* transformation.
*/
void Reset()
{
m_m = 0.5;
m_s = m_l = 0.0;
m_h = m_r = 1.0;
}
/*!
* Exchanges two %DisplayFunction objects.
*/
friend void Swap( DisplayFunction& x, DisplayFunction& y )
{
pcl::Swap( x.m_m, y.m_m );
pcl::Swap( x.m_s, y.m_s );
pcl::Swap( x.m_h, y.m_h );
pcl::Swap( x.m_l, y.m_l );
pcl::Swap( x.m_r, y.m_r );
pcl::Swap( x.m_clip, y.m_clip );
pcl::Swap( x.m_tbkg, y.m_tbkg );
pcl::Swap( x.m_link, y.m_link );
}
private:
DVector m_m; // midtones balance
DVector m_s; // shadows clipping point
DVector m_h; // highlights clipping point
DVector m_l; // shadows dynamic range expansion
DVector m_r; // highlights dynamic range expansion
double m_clip = __PCL_AUTOSTRETCH_DEFAULT_CLIP; // auto-stretch clipping point
double m_tbkg = __PCL_AUTOSTRETCH_DEFAULT_TBGD; // auto-stretch target background
bool m_link = __PCL_AUTOSTRETCH_DEFAULT_LINK; // auto-stretch linked RGB
/*
* Display function transformation.
*/
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;
};
// ----------------------------------------------------------------------------
} // pcl
#endif // __PCL_DisplayFunction_h
// ----------------------------------------------------------------------------
// EOF pcl/DisplayFunction.h - Released 2022-03-12T18:59:29Z