File indexing completed on 2024-12-22 04:10:01
0001 /* 0002 * SPDX-FileCopyrightText: 2014 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "kis_bspline_2d.h" 0008 0009 #include <kis_debug.h> 0010 #include <limits> 0011 0012 #include "einspline/bspline_create.h" 0013 #include "einspline/bspline_eval_std_s.h" 0014 0015 #include "kis_bspline_p.h" 0016 0017 namespace KisBSplines { 0018 0019 struct Q_DECL_HIDDEN KisBSpline2D::Private 0020 { 0021 BorderCondition bcX; 0022 BorderCondition bcY; 0023 0024 UBspline_2d_s* spline; 0025 }; 0026 0027 KisBSpline2D::KisBSpline2D(float xStart, float xEnd, int numSamplesX, BorderCondition bcX, 0028 float yStart, float yEnd, int numSamplesY, BorderCondition bcY) 0029 : m_d(new Private) 0030 { 0031 m_xStart = xStart; 0032 m_xEnd = xEnd; 0033 m_numSamplesX = numSamplesX; 0034 0035 m_yStart = yStart; 0036 m_yEnd = yEnd; 0037 m_numSamplesY = numSamplesY; 0038 0039 m_d->bcX = bcX; 0040 m_d->bcY = bcY; 0041 0042 m_d->spline = 0; 0043 } 0044 0045 KisBSpline2D::~KisBSpline2D() 0046 { 0047 if (m_d->spline) { 0048 destroy_Bspline(m_d->spline); 0049 } 0050 } 0051 0052 void KisBSpline2D::initializeSplineImpl(const QVector<float> &values) 0053 { 0054 Ugrid xGrid; 0055 xGrid.start = m_xStart; 0056 xGrid.end = m_xEnd; 0057 xGrid.num = m_numSamplesX; 0058 xGrid.delta = 0.0; 0059 xGrid.delta_inv = 0.0; 0060 0061 Ugrid yGrid; 0062 yGrid.start = m_yStart; 0063 yGrid.end = m_yEnd; 0064 yGrid.num = m_numSamplesY; 0065 yGrid.delta = 0.0; 0066 yGrid.delta_inv = 0.0; 0067 0068 BCtype_s bctypeX; 0069 bctypeX.lCode = bctypeX.rCode = convertBorderType(m_d->bcX); 0070 bctypeX.lVal = 0.0; 0071 bctypeX.rVal = 0.0; 0072 0073 BCtype_s bctypeY; 0074 bctypeY.lCode = bctypeY.rCode = convertBorderType(m_d->bcY); 0075 bctypeY.lVal = 0.0; 0076 bctypeY.rVal = 0.0; 0077 0078 m_d->spline = 0079 create_UBspline_2d_s(xGrid, yGrid, 0080 bctypeX, bctypeY, 0081 const_cast<float*>(values.constData())); 0082 } 0083 0084 float KisBSpline2D::value(float x, float y) const 0085 { 0086 /** 0087 * The spline works for an open interval only, so include the last point 0088 * explicitly 0089 */ 0090 0091 if (x == m_xEnd) { 0092 x -= x * std::numeric_limits<float>::epsilon(); 0093 } 0094 0095 if (y == m_yEnd) { 0096 y -= y * std::numeric_limits<float>::epsilon(); 0097 } 0098 0099 KIS_ASSERT_RECOVER_NOOP(x >= m_xStart && x < m_xEnd); 0100 KIS_ASSERT_RECOVER_NOOP(y >= m_yStart && y < m_yEnd); 0101 0102 float value; 0103 eval_UBspline_2d_s (m_d->spline, x, y, &value); 0104 0105 return value; 0106 } 0107 0108 BorderCondition KisBSpline2D::borderConditionX() const 0109 { 0110 return m_d->bcX; 0111 } 0112 0113 BorderCondition KisBSpline2D::borderConditionY() const 0114 { 0115 return m_d->bcY; 0116 } 0117 0118 }