PCL
PixelInterpolation.h
Go to the documentation of this file.
1 // ____ ______ __
2 // / __ \ / ____// /
3 // / /_/ // / / /
4 // / ____// /___ / /___ PixInsight Class Library
5 // /_/ \____//_____/ PCL 2.1.19
6 // ----------------------------------------------------------------------------
7 // pcl/PixelInterpolation.h - Released 2019-11-07T10:59:34Z
8 // ----------------------------------------------------------------------------
9 // This file is part of the PixInsight Class Library (PCL).
10 // PCL is a multiplatform C++ framework for development of PixInsight modules.
11 //
12 // Copyright (c) 2003-2019 Pleiades Astrophoto S.L. All Rights Reserved.
13 //
14 // Redistribution and use in both source and binary forms, with or without
15 // modification, is permitted provided that the following conditions are met:
16 //
17 // 1. All redistributions of source code must retain the above copyright
18 // notice, this list of conditions and the following disclaimer.
19 //
20 // 2. All redistributions in binary form must reproduce the above copyright
21 // notice, this list of conditions and the following disclaimer in the
22 // documentation and/or other materials provided with the distribution.
23 //
24 // 3. Neither the names "PixInsight" and "Pleiades Astrophoto", nor the names
25 // of their contributors, may be used to endorse or promote products derived
26 // from this software without specific prior written permission. For written
27 // permission, please contact info@pixinsight.com.
28 //
29 // 4. All products derived from this software, in any form whatsoever, must
30 // reproduce the following acknowledgment in the end-user documentation
31 // and/or other materials provided with the product:
32 //
33 // "This product is based on software from the PixInsight project, developed
34 // by Pleiades Astrophoto and its contributors (http://pixinsight.com/)."
35 //
36 // Alternatively, if that is where third-party acknowledgments normally
37 // appear, this acknowledgment must be reproduced in the product itself.
38 //
39 // THIS SOFTWARE IS PROVIDED BY PLEIADES ASTROPHOTO AND ITS CONTRIBUTORS
40 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
41 // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PLEIADES ASTROPHOTO OR ITS
43 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
44 // EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, BUSINESS
45 // INTERRUPTION; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; AND LOSS OF USE,
46 // DATA OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
49 // POSSIBILITY OF SUCH DAMAGE.
50 // ----------------------------------------------------------------------------
51 
52 #ifndef __PCL_PixelInterpolation_h
53 #define __PCL_PixelInterpolation_h
54 
56 
57 #include <pcl/Defs.h>
58 #include <pcl/Diagnostics.h>
59 
60 #include <pcl/AutoPointer.h>
64 #include <pcl/Exception.h>
67 #include <pcl/PixelTraits.h>
68 #include <pcl/Point.h>
69 #include <pcl/String.h>
70 
71 #ifdef _MSC_VER
72 # pragma warning( push )
73 # pragma warning( disable : 4267 ) // conversion from 'size_t' to ...
74 #endif
75 
76 namespace pcl
77 {
78 
79 // ----------------------------------------------------------------------------
80 
97 class PCL_CLASS PixelInterpolation
98 {
99 public:
100 
108  template <class P>
109  class PCL_CLASS Interpolator
110  {
111  public:
112 
116  typedef typename P::sample sample;
117 
147  const sample* data, int width, int height, bool unclipped = false ) :
148  m_interpolation( interpolation ),
149  m_unclipped( unclipped )
150  {
151  if ( !m_interpolation.IsNull() )
152  m_interpolation->Initialize( data, width, height );
153  }
154 
158  Interpolator( const Interpolator& ) = delete;
159 
163  Interpolator( Interpolator&& ) = default;
164 
168  virtual ~Interpolator()
169  {
170  }
171 
177  {
178  PCL_PRECONDITION( !m_interpolation.IsNull() )
179  return *m_interpolation;
180  }
181 
187  {
188  PCL_PRECONDITION( !m_interpolation.IsNull() )
189  return *m_interpolation;
190  }
191 
203  sample operator()( double x, double y ) const
204  {
205  PCL_PRECONDITION( !m_interpolation.IsNull() )
206  double r = (*m_interpolation)( x, y );
207  if ( !m_unclipped )
208  {
209  if ( r > P::MaxSampleValue() )
210  return P::MaxSampleValue();
211  if ( r < P::MinSampleValue() )
212  return P::MinSampleValue();
213  }
214  return P::FloatToSample( r );
215  }
216 
223  template <typename T>
224  sample operator()( const GenericPoint<T>& p ) const
225  {
226  return operator()( p.x, p.y );
227  }
228 
229  private:
230 
232  bool m_unclipped : 1;
233  };
234 
235  // -------------------------------------------------------------------------
236 
240  PixelInterpolation() = default;
241 
245  PixelInterpolation( const PixelInterpolation& ) = default;
246 
251  {
252  }
253 
257  virtual String Description() const = 0;
258 
269  virtual bool IsThreadSafe() const
270  {
271  return true;
272  }
273 
286  template <class P, class T>
287  Interpolator<P>* NewInterpolator( const T* data, int width, int height, bool unclipped = false ) const
288  {
289  return new Interpolator<P>( NewInterpolation( data ), data, width, height, unclipped );
290  }
291 
292 protected:
293 
295  NewInterpolation( const FloatPixelTraits::sample* ) const
296  {
297  throw NotImplemented( *this, "Interpolate 32-bit floating point images" );
298  }
299 
301  NewInterpolation( const DoublePixelTraits::sample* ) const
302  {
303  throw NotImplemented( *this, "Interpolate 64-bit floating point images" );
304  }
305 
307  NewInterpolation( const ComplexPixelTraits::sample* ) const
308  {
309  throw NotImplemented( *this, "Interpolate 32-bit complex images" );
310  }
311 
313  NewInterpolation( const DComplexPixelTraits::sample* ) const
314  {
315  throw NotImplemented( *this, "Interpolate 64-bit complex images" );
316  }
317 
319  NewInterpolation( const UInt8PixelTraits::sample* ) const
320  {
321  throw NotImplemented( *this, "Interpolate 8-bit integer images" );
322  }
323 
325  NewInterpolation( const UInt16PixelTraits::sample* ) const
326  {
327  throw NotImplemented( *this, "Interpolate 16-bit integer images" );
328  }
329 
331  NewInterpolation( const UInt32PixelTraits::sample* ) const
332  {
333  throw NotImplemented( *this, "Interpolate 32-bit integer images" );
334  }
335 };
336 
337 // ----------------------------------------------------------------------------
338 
352 {
353 public:
354 
359 
364 
367  String Description() const override
368  {
369  return "Nearest neighbor interpolation";
370  }
371 
372 private:
373 
375  NewInterpolation( const FloatPixelTraits::sample* ) const override
376  {
378  }
379 
381  NewInterpolation( const DoublePixelTraits::sample* ) const override
382  {
384  }
385 
387  NewInterpolation( const UInt8PixelTraits::sample* ) const override
388  {
390  }
391 
393  NewInterpolation( const UInt16PixelTraits::sample* ) const override
394  {
396  }
397 
399  NewInterpolation( const UInt32PixelTraits::sample* ) const override
400  {
402  }
403 };
404 
405 // ----------------------------------------------------------------------------
406 
420 {
421 public:
422 
426  BilinearPixelInterpolation() = default;
427 
432 
435  String Description() const override
436  {
437  return "Bilinear interpolation";
438  }
439 
440 private:
441 
443  NewInterpolation( const FloatPixelTraits::sample* ) const override
444  {
446  }
447 
449  NewInterpolation( const DoublePixelTraits::sample* ) const override
450  {
452  }
453 
455  NewInterpolation( const UInt8PixelTraits::sample* ) const override
456  {
458  }
459 
461  NewInterpolation( const UInt16PixelTraits::sample* ) const override
462  {
464  }
465 
467  NewInterpolation( const UInt32PixelTraits::sample* ) const override
468  {
470  }
471 };
472 
473 // ----------------------------------------------------------------------------
474 
488 {
489 public:
490 
499  BicubicSplinePixelInterpolation( double clamp = __PCL_BICUBIC_SPLINE_CLAMPING_THRESHOLD ) :
500  m_clamp( clamp )
501  {
502  }
503 
508 
511  String Description() const override
512  {
513  return String().Format( "Bicubic spline interpolation, c=%.2f", m_clamp );
514  }
515 
516 private:
517 
518  float m_clamp;
519 
521  NewInterpolation( const FloatPixelTraits::sample* ) const override
522  {
524  }
525 
527  NewInterpolation( const DoublePixelTraits::sample* ) const override
528  {
530  }
531 
533  NewInterpolation( const UInt8PixelTraits::sample* ) const override
534  {
536  }
537 
539  NewInterpolation( const UInt16PixelTraits::sample* ) const override
540  {
542  }
543 
545  NewInterpolation( const UInt32PixelTraits::sample* ) const override
546  {
548  }
549 };
550 
561 {
562 public:
563 
572  BicubicPixelInterpolation( double c = __PCL_BICUBIC_SPLINE_CLAMPING_THRESHOLD ) :
574  {
575  }
576 
581 };
582 
583 // ----------------------------------------------------------------------------
584 
598 {
599 public:
600 
605 
610 
613  String Description() const override
614  {
615  return "Bicubic B-spline interpolation";
616  }
617 
618 private:
619 
621  NewInterpolation( const FloatPixelTraits::sample* ) const override
622  {
624  }
625 
627  NewInterpolation( const DoublePixelTraits::sample* ) const override
628  {
630  }
631 
633  NewInterpolation( const UInt8PixelTraits::sample* ) const override
634  {
636  }
637 
639  NewInterpolation( const UInt16PixelTraits::sample* ) const override
640  {
642  }
643 
645  NewInterpolation( const UInt32PixelTraits::sample* ) const override
646  {
648  }
649 };
650 
651 // ----------------------------------------------------------------------------
652 
667 {
668 public:
669 
682  BicubicFilterPixelInterpolation( int rh, int rv, const CubicFilter& filter ) :
683  m_rh( Max( 1, rh ) ),
684  m_rv( Max( 1, rv ) )
685  {
686  PCL_PRECONDITION( rh >= 1 )
687  PCL_PRECONDITION( rv >= 1 )
688  m_filter = filter.Clone();
689  }
690 
695  m_rh( x.m_rh ),
696  m_rv( x.m_rv )
697  {
698  m_filter = x.m_filter->Clone();
699  }
700 
705 
710  {
711  }
712 
715  String Description() const override
716  {
717  return "Bicubic interpolation, " + m_filter->Description().AppendFormat( " (%dx%d)", 2*m_rh + 1, 2*m_rv + 1 );
718  }
719 
724  const CubicFilter& Filter() const
725  {
726  return *m_filter;
727  }
728 
729 private:
730 
731  int m_rh, m_rv;
732  AutoPointer<CubicFilter> m_filter;
733 
735  NewInterpolation( const FloatPixelTraits::sample* ) const override
736  {
737  return new BicubicFilterInterpolation<FloatPixelTraits::sample>( m_rh, m_rv, *m_filter );
738  }
739 
741  NewInterpolation( const DoublePixelTraits::sample* ) const override
742  {
743  return new BicubicFilterInterpolation<DoublePixelTraits::sample>( m_rh, m_rv, *m_filter );
744  }
745 
747  NewInterpolation( const UInt8PixelTraits::sample* ) const override
748  {
749  return new BicubicFilterInterpolation<UInt8PixelTraits::sample>( m_rh, m_rv, *m_filter );
750  }
751 
753  NewInterpolation( const UInt16PixelTraits::sample* ) const override
754  {
755  return new BicubicFilterInterpolation<UInt16PixelTraits::sample>( m_rh, m_rv, *m_filter );
756  }
757 
759  NewInterpolation( const UInt32PixelTraits::sample* ) const override
760  {
761  return new BicubicFilterInterpolation<UInt32PixelTraits::sample>( m_rh, m_rv, *m_filter );
762  }
763 };
764 
765 // ----------------------------------------------------------------------------
766 
782 {
783 public:
784 
801  LanczosPixelInterpolation( int n = 3, float clamp = 0.3 ) :
802  m_n( Max( 1, n ) ),
803  m_clamp( clamp )
804  {
805  PCL_PRECONDITION( n >= 1 )
806  PCL_PRECONDITION( clamp < 0 || 0 <= clamp && clamp <= 1 )
807  }
808 
813 
816  String Description() const override
817  {
818  String desc = String().Format( "Lanczos-%d interpolation", m_n );
819  if ( m_clamp >= 0 )
820  desc.AppendFormat( ", c=%.2f", m_clamp );
821  return desc;
822  }
823 
824 private:
825 
826  int m_n; // filter order
827  float m_clamp; // clamping threshold (enabled if >= 0)
828 
830  NewInterpolation( const FloatPixelTraits::sample* ) const override
831  {
832  return new LanczosInterpolation<FloatPixelTraits::sample>( m_n, m_clamp );
833  }
834 
836  NewInterpolation( const DoublePixelTraits::sample* ) const override
837  {
838  return new LanczosInterpolation<DoublePixelTraits::sample>( m_n, m_clamp );
839  }
840 
842  NewInterpolation( const UInt8PixelTraits::sample* ) const override
843  {
844  return new LanczosInterpolation<UInt8PixelTraits::sample>( m_n, m_clamp );
845  }
846 
848  NewInterpolation( const UInt16PixelTraits::sample* ) const override
849  {
850  return new LanczosInterpolation<UInt16PixelTraits::sample>( m_n, m_clamp );
851  }
852 
854  NewInterpolation( const UInt32PixelTraits::sample* ) const override
855  {
856  return new LanczosInterpolation<UInt32PixelTraits::sample>( m_n, m_clamp );
857  }
858 };
859 
860 // ----------------------------------------------------------------------------
861 
878 {
879 public:
880 
891  Lanczos3LUTPixelInterpolation( float clamp = 0.3F ) :
892  m_clamp( clamp )
893  {
894  PCL_PRECONDITION( clamp < 0 || 0 <= clamp && clamp <= 1 )
895  }
896 
901 
904  String Description() const override
905  {
906  String desc( "Lanczos-3 LUT interpolation" );
907  if ( m_clamp >= 0 )
908  desc.AppendFormat( ", c=%.2f", m_clamp );
909  return desc;
910  }
911 
912 private:
913 
914  float m_clamp; // clamping threshold (enabled if >= 0)
915 
917  NewInterpolation( const FloatPixelTraits::sample* ) const override
918  {
920  }
921 
923  NewInterpolation( const DoublePixelTraits::sample* ) const override
924  {
926  }
927 
929  NewInterpolation( const UInt8PixelTraits::sample* ) const override
930  {
932  }
933 
935  NewInterpolation( const UInt16PixelTraits::sample* ) const override
936  {
938  }
939 
941  NewInterpolation( const UInt32PixelTraits::sample* ) const override
942  {
944  }
945 };
946 
947 // ----------------------------------------------------------------------------
948 
965 {
966 public:
967 
978  Lanczos4LUTPixelInterpolation( float clamp = 0.3F ) :
979  m_clamp( Range( clamp, 0.0F, 1.0F ) )
980  {
981  PCL_PRECONDITION( clamp < 0 || 0 <= clamp && clamp <= 1 )
982  }
983 
988 
991  String Description() const override
992  {
993  String desc( "Lanczos-4 LUT interpolation" );
994  if ( m_clamp >= 0 )
995  desc.AppendFormat( ", c=%.2f", m_clamp );
996  return desc;
997  }
998 
999 private:
1000 
1001  float m_clamp; // clamping threshold (enabled if >= 0)
1002 
1004  NewInterpolation( const FloatPixelTraits::sample* ) const override
1005  {
1007  }
1008 
1010  NewInterpolation( const DoublePixelTraits::sample* ) const override
1011  {
1013  }
1014 
1016  NewInterpolation( const UInt8PixelTraits::sample* ) const override
1017  {
1019  }
1020 
1022  NewInterpolation( const UInt16PixelTraits::sample* ) const override
1023  {
1025  }
1026 
1028  NewInterpolation( const UInt32PixelTraits::sample* ) const override
1029  {
1031  }
1032 };
1033 
1034 // ----------------------------------------------------------------------------
1035 
1052 {
1053 public:
1054 
1065  Lanczos5LUTPixelInterpolation( float clamp = 0.3F ) :
1066  m_clamp( Range( clamp, 0.0F, 1.0F ) )
1067  {
1068  PCL_PRECONDITION( clamp < 0 || 0 <= clamp && clamp <= 1 )
1069  }
1070 
1075 
1078  String Description() const override
1079  {
1080  String desc( "Lanczos-5 LUT interpolation" );
1081  if ( m_clamp >= 0 )
1082  desc.AppendFormat( ", c=%.2f", m_clamp );
1083  return desc;
1084  }
1085 
1086 private:
1087 
1088  float m_clamp; // clamping threshold (enabled if >= 0)
1089 
1091  NewInterpolation( const FloatPixelTraits::sample* ) const override
1092  {
1094  }
1095 
1097  NewInterpolation( const DoublePixelTraits::sample* ) const override
1098  {
1100  }
1101 
1103  NewInterpolation( const UInt8PixelTraits::sample* ) const override
1104  {
1106  }
1107 
1109  NewInterpolation( const UInt16PixelTraits::sample* ) const override
1110  {
1112  }
1113 
1115  NewInterpolation( const UInt32PixelTraits::sample* ) const override
1116  {
1118  }
1119 };
1120 
1121 // ----------------------------------------------------------------------------
1122 
1123 } // pcl
1124 
1125 #ifdef _MSC_VER
1126 # pragma warning( pop )
1127 #endif
1128 
1129 #endif // __PCL_PixelInterpolation_h
1130 
1131 // ----------------------------------------------------------------------------
1132 // EOF pcl/PixelInterpolation.h - Released 2019-11-07T10:59:34Z
Bicubic filter interpolation algorithms.
traits_type::sample sample
Definition: PixelTraits.h:4635
A generic point in the two-dimensional space.
Definition: Point.h:99
sample operator()(const GenericPoint< T > &p) const
BidimensionalInterpolation< sample > & Interpolation()
sample operator()(double x, double y) const
Lanczos pixel interpolation.
const CubicFilter & Filter() const
Two dimensional LUT-based 3rd-order Lanczos interpolation algorithm.
Lanczos 3rd-order LUT-based pixel interpolation.
PCL root namespace.
Definition: AbstractImage.h:76
const BidimensionalInterpolation< sample > & Interpolation() const
A smart pointer with sole object ownership and optional automatic object destruction.
Definition: AutoPointer.h:241
An exception that indicates an unsupported feature.
Definition: Exception.h:315
traits_type::sample sample
Definition: PixelTraits.h:364
Lanczos 5th-order LUT-based pixel interpolation.
Two dimensional Lanczos interpolation algorithm.
Bicubic spline pixel interpolation.
Lanczos 3rd-order LUT-based pixel interpolation.
constexpr const T & Range(const T &x, const T &a, const T &b)
Definition: Utility.h:190
Generic two-dimensional pixel interpolator.
String & Format(const_c_string8 fmt,...)
Definition: String.h:10865
Bilinear pixel interpolation.
Bicubic B-Spline Interpolation Algorithm.
Two dimensional LUT-based 4th-order Lanczos interpolation algorithm.
Unicode (UTF-16) string.
Definition: String.h:7911
constexpr const T & Max(const T &a, const T &b)
Definition: Utility.h:119
BicubicSplinePixelInterpolation(double clamp=__PCL_BICUBIC_SPLINE_CLAMPING_THRESHOLD)
component x
Abscissa (horizontal, or X-axis coordinate).
Definition: Point.h:111
Generic complex number.
Definition: Complex.h:83
LanczosPixelInterpolation(int n=3, float clamp=0.3)
Bicubic B-spline pixel interpolation.
virtual CubicFilter * Clone() const
BicubicFilterPixelInterpolation(int rh, int rv, const CubicFilter &filter)
BicubicFilterPixelInterpolation(const BicubicFilterPixelInterpolation &x)
Two dimensional LUT-based 5th-order Lanczos interpolation algorithm.
Interpolator(BidimensionalInterpolation< sample > *interpolation, const sample *data, int width, int height, bool unclipped=false)
virtual bool IsThreadSafe() const
traits_type::sample sample
Definition: PixelTraits.h:3798
NearestNeighbor pixel interpolation.
Bicubic pixel interpolation - an alias for BicubicSplinePixelInterpolation.
String & AppendFormat(const_c_string8 fmt,...)
Definition: String.h:10887
Mitchell-Netravali parameterized cubic filters.
Two-dimensional nearest neighbor interpolation algorithm.
String Description() const override
Abstract root base class for all pixel interpolation algorithms.
component y
Ordinate (vertical, or Y-axis coordinate).
Definition: Point.h:112
Bicubic spline interpolation algorithm.
BicubicPixelInterpolation(double c=__PCL_BICUBIC_SPLINE_CLAMPING_THRESHOLD)
String Description() const override
traits_type::sample sample
Definition: PixelTraits.h:2961
traits_type::sample sample
Definition: PixelTraits.h:929
Bilinear interpolation algorithm.
Pixel interpolation based on Mitchell-Netravali parameterized bicubic filters.
Interpolator< P > * NewInterpolator(const T *data, int width, int height, bool unclipped=false) const