<commit_before>// This file is distributed under the MIT license.
// See the LICENSE file for details.

#pragma once

#ifndef VSNRAY_TEXTURE_SAMPLER1D_H
#define VSNRAY_TEXTURE_SAMPLER1D_H 1

#include <visionaray/math/math.h>

#include "sampler_common.h"
#include "texture_common.h"


namespace visionaray
{
namespace detail
{


template <typename ReturnT, typename InternalT, typename FloatT, typename TexelT>
inline ReturnT nearest(
        ReturnT                                 /* */,
        InternalT                               /* */,
        TexelT const*                           tex,
        FloatT                                  coord,
        FloatT                                  texsize,
        std::array<tex_address_mode, 1> const&  address_mode
        )
{
    coord = map_tex_coord(coord, address_mode);

    FloatT lo = floor(coord * texsize);
    lo = clamp(lo, FloatT(0.0f), texsize - 1);
    return point(tex, lo, ReturnT());
}


template <typename ReturnT, typename InternalT, typename FloatT, typename TexelT>
inline ReturnT linear(
        ReturnT                                 /* */,
        InternalT                               /* */,
        TexelT const*                           tex,
        FloatT                                  coord,
        FloatT                                  texsize,
        std::array<tex_address_mode, 1> const&  address_mode
        )
{
    coord = map_tex_coord(coord, address_mode);

    FloatT texcoordf( coord * texsize - FloatT(0.5) );
    texcoordf = clamp( texcoordf, FloatT(0.0), texsize - 1 );

    FloatT lo = floor(texcoordf);
    FloatT hi = ceil(texcoordf);


    InternalT samples[2] =
    {
        InternalT( point(tex, lo, ReturnT()) ),
        InternalT( point(tex, hi, ReturnT()) )
    };

    auto u = texcoordf - lo;

    return lerp( samples[0], samples[1], u );
}


template <typename ReturnT, typename InternalT, typename FloatT, typename TexelT>
inline ReturnT cubic2(
        ReturnT                                 /* */,
        InternalT                               /* */,
        TexelT const*                           tex,
        FloatT                                  coord,
        FloatT                                  texsize,
        std::array<tex_address_mode, 1> const&  address_mode
        )
{
    bspline::w0_func<FloatT> w0;
    bspline::w1_func<FloatT> w1;
    bspline::w2_func<FloatT> w2;
    bspline::w3_func<FloatT> w3;

    auto x = coord * texsize - FloatT(0.5);
    auto floorx = floor(x);
    auto fracx  = x - floor(x);

    auto tmp0 = ( w1(fracx) ) / ( w0(fracx) + w1(fracx) );
    auto h0   = ( floorx - FloatT(0.5) + tmp0 ) / texsize;

    auto tmp1 = ( w3(fracx) ) / ( w2(fracx) + w3(fracx) );
    auto h1   = ( floorx + FloatT(1.5) + tmp1 ) / texsize;

    auto f_0  = InternalT( linear(ReturnT(), InternalT(), tex, h0, texsize, address_mode) );
    auto f_1  = InternalT( linear(ReturnT(), InternalT(), tex, h1, texsize, address_mode) );

    return ReturnT(g0(fracx) * f_0 + g1(fracx) * f_1);
}


template <typename ReturnT, typename W0, typename W1, typename W2, typename W3, typename FloatT, typename TexelT>
inline ReturnT cubic(TexelT const* tex, FloatT coord, FloatT texsize, W0 w0, W1 w1, W2 w2, W3 w3)
{

    FloatT x = coord * texsize - FloatT(0.5);
    FloatT floorx = floor( x );
    FloatT fracx = x - floor( x );

    FloatT pos[4] =
    {
        FloatT( floorx - 1 ),
        FloatT( floorx ),
        FloatT( floorx + 1 ),
        FloatT( floorx + 2 )
    };

    for (size_t i = 0; i < 4; ++i)
    {
        pos[i] = clamp(pos[i], FloatT(0.0), texsize - FloatT(1.0));
    }

#define TEX(x) (point(tex,x, ReturnT()))
    return w0(fracx) * TEX(pos[0]) + w1(fracx) * TEX(pos[1]) + w2(fracx) * TEX(pos[2]) + w3(fracx) * TEX(pos[3]);
#undef TEX
}


//-------------------------------------------------------------------------------------------------
// Dispatch function to choose among filtering algorithms
//

template <typename ReturnT, typename FloatT, typename TexelT, typename InternalT>
inline ReturnT tex1D_impl_choose_filter(
        ReturnT                                 /* */,
        InternalT                               /* */,
        TexelT const&                           tex,
        FloatT                                  coord,
        FloatT                                  texsize,
        tex_filter_mode                         filter_mode,
        std::array<tex_address_mode, 1> const&  address_mode
        )
{
    switch (filter_mode)
    {

    default:
        // fall-through
    case visionaray::Nearest:
        return nearest(
                ReturnT(),
                InternalT(),
                tex,
                coord,
                texsize,
                address_mode
                );

    case visionaray::Linear:
        return linear(
                ReturnT(),
                InternalT(),
                tex,
                coord,
                texsize,
                address_mode
                );

    case visionaray::BSpline:
        return cubic2(
                ReturnT(),
                InternalT(),
                tex,
                coord,
                texsize,
                address_mode
                );

    }

}


//-------------------------------------------------------------------------------------------------
// Dispatch function overloads to deduce texture type and internal texture type
//

// float

template <typename T>
inline T tex1D_impl_expand_types(
        T const*                                tex,
        float                                   coord,
        float                                   texsize,
        tex_filter_mode                         filter_mode,
        std::array<tex_address_mode, 1> const&  address_mode
        )<commit_msg>Reenable Catmull-Rom filtering for 1-D textures<commit_after>// This file is distributed under the MIT license.
// See the LICENSE file for details.

#pragma once

#ifndef VSNRAY_TEXTURE_SAMPLER1D_H
#define VSNRAY_TEXTURE_SAMPLER1D_H 1

#include <visionaray/math/math.h>

#include "sampler_common.h"
#include "texture_common.h"


namespace visionaray
{
namespace detail
{


template <typename ReturnT, typename InternalT, typename FloatT, typename TexelT>
inline ReturnT nearest(
        ReturnT                                 /* */,
        InternalT                               /* */,
        TexelT const*                           tex,
        FloatT                                  coord,
        FloatT                                  texsize,
        std::array<tex_address_mode, 1> const&  address_mode
        )
{
    coord = map_tex_coord(coord, address_mode);

    FloatT lo = floor(coord * texsize);
    lo = clamp(lo, FloatT(0.0f), texsize - 1);
    return point(tex, lo, ReturnT());
}


template <typename ReturnT, typename InternalT, typename FloatT, typename TexelT>
inline ReturnT linear(
        ReturnT                                 /* */,
        InternalT                               /* */,
        TexelT const*                           tex,
        FloatT                                  coord,
        FloatT                                  texsize,
        std::array<tex_address_mode, 1> const&  address_mode
        )
{
    coord = map_tex_coord(coord, address_mode);

    FloatT texcoordf( coord * texsize - FloatT(0.5) );
    texcoordf = clamp( texcoordf, FloatT(0.0), texsize - 1 );

    FloatT lo = floor(texcoordf);
    FloatT hi = ceil(texcoordf);


    InternalT samples[2] =
    {
        InternalT( point(tex, lo, ReturnT()) ),
        InternalT( point(tex, hi, ReturnT()) )
    };

    auto u = texcoordf - lo;

    return lerp( samples[0], samples[1], u );
}


template <typename ReturnT, typename InternalT, typename FloatT, typename TexelT>
inline ReturnT cubic2(
        ReturnT                                 /* */,
        InternalT                               /* */,
        TexelT const*                           tex,
        FloatT                                  coord,
        FloatT                                  texsize,
        std::array<tex_address_mode, 1> const&  address_mode
        )
{
    bspline::w0_func<FloatT> w0;
    bspline::w1_func<FloatT> w1;
    bspline::w2_func<FloatT> w2;
    bspline::w3_func<FloatT> w3;

    auto x = coord * texsize - FloatT(0.5);
    auto floorx = floor(x);
    auto fracx  = x - floor(x);

    auto tmp0 = ( w1(fracx) ) / ( w0(fracx) + w1(fracx) );
    auto h0   = ( floorx - FloatT(0.5) + tmp0 ) / texsize;

    auto tmp1 = ( w3(fracx) ) / ( w2(fracx) + w3(fracx) );
    auto h1   = ( floorx + FloatT(1.5) + tmp1 ) / texsize;

    auto f_0  = InternalT( linear(ReturnT(), InternalT(), tex, h0, texsize, address_mode) );
    auto f_1  = InternalT( linear(ReturnT(), InternalT(), tex, h1, texsize, address_mode) );

    return ReturnT(g0(fracx) * f_0 + g1(fracx) * f_1);
}


template <
    typename ReturnT,
    typename InternalT,
    typename FloatT,
    typename TexelT,
    typename W0,
    typename W1,
    typename W2,
    typename W3
    >
inline ReturnT cubic(
        ReturnT                                 /* */,
        InternalT                               /* */,
        TexelT const*                           tex,
        FloatT                                  coord,
        FloatT                                  texsize,
        std::array<tex_address_mode, 1> const&  address_mode,
        W0                                      w0,
        W1                                      w1,
        W2                                      w2,
        W3                                      w3
        )
{
    coord = map_tex_coord(coord, address_mode);

    auto x = coord * texsize - FloatT(0.5);
    auto floorx = floor(x);
    auto fracx = x - floor(x);

    FloatT pos[4] =
    {
        floorx - 1,
        floorx,
        floorx + 1,
        floorx + 2
    };

    for (size_t i = 0; i < 4; ++i)
    {
        pos[i] = clamp(pos[i], FloatT(0.0), texsize - FloatT(1.0));
    }

    auto sample = [&](int i) -> InternalT
    {
        return InternalT( point(tex, pos[i], ReturnT()) );
    };

    return w0(fracx) * sample(0) + w1(fracx) * sample(1) + w2(fracx) * sample(2) + w3(fracx) * sample(3);
}


//-------------------------------------------------------------------------------------------------
// Dispatch function to choose among filtering algorithms
//

template <typename ReturnT, typename FloatT, typename TexelT, typename InternalT>
inline ReturnT tex1D_impl_choose_filter(
        ReturnT                                 /* */,
        InternalT                               /* */,
        TexelT const&                           tex,
        FloatT                                  coord,
        FloatT                                  texsize,
        tex_filter_mode                         filter_mode,
        std::array<tex_address_mode, 1> const&  address_mode
        )
{
    switch (filter_mode)
    {

    default:
        // fall-through
    case visionaray::Nearest:
        return nearest(
                ReturnT(),
                InternalT(),
                tex,
                coord,
                texsize,
                address_mode
                );

    case visionaray::Linear:
        return linear(
                ReturnT(),
                InternalT(),
                tex,
                coord,
                texsize,
                address_mode
                );

    case visionaray::BSpline:
        return cubic2(
                ReturnT(),
                InternalT(),
                tex,
                coord,
                texsize,
                address_mode
                );

    case visionaray::CardinalSpline:
        return cubic(
                ReturnT(),
                InternalT(),
                tex,
                coord,
                texsize,
                address_mode,
                cspline::w0_func<FloatT>(),
                cspline::w1_func<FloatT>(),
                cspline::w2_func<FloatT>(),
                cspline::w3_func<FloatT>()
                );

    }

}


//-------------------------------------------------------------------------------------------------
// Dispatch function overloads to deduce texture type and internal texture type
//

// float

template <typename T>
inline T tex1D_impl_expand_types(
        T const*                                tex,
        float                                   coord,
        float                                   texsize,
        tex_filter_mode                         filter_mode,
        std::array<tex_address_mode, 1> const&  address_mode
        )
{'fraction_non_alphanumeric': 0.12553292278540976, 'fraction_numerical': 0.014527080372651192, 'mean_word_length': 1.217612044817927, 'pattern_counts': {'":': 0, '<': 42, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 48, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7549004', 'n_tokens_mistral': 3768, 'n_tokens_neox': 3524, 'n_words': 853}