packrange.h

Back to Deprecated

pastel/gfx/image_processing/

// Description: Packing of a scalar image to [0, 1] range
// Documentation: undocumented.txt

#ifndef PASTELGFX_PACKRANGE_H
#define PASTELGFX_PACKRANGE_H

#include "pastel/sys/array.h"
#include "pastel/sys/view/view_visit.h"
#include "pastel/sys/view/view_tools.h"
#include "pastel/sys/math/constants.h"

namespace Pastel
{

    namespace PackRange_
    {

        template <typename Real>
        class MinMaxFunctor
        {
        public:
            MinMaxFunctor(
                Real& min,
                Real& max)
                : min_(min)
                , max_(max)
            {
            }

            void operator()(const Real& that) const
            {
                if (that < min_)
                {
                    min_ = that;
                }
                if (that > max_)
                {
                    max_ = that;
                }
            }

        private:
            Real& min_;
            Real& max_;
        };

        template <typename Real>
        class ScalingFunctor
        {
        public:
            ScalingFunctor(
                const Real& min,
                const Real& newMin,
                const Real& scale)
                : min_(min)
                , newMin_(newMin)
                , scale_(scale)

            {
            }

            void operator()(Real& that) const
            {
                that = (that - min_) * scale_ + newMin_;
            }

        private:
            const Real& min_;
            const Real& newMin_;
            const Real& scale_;
        };
    }

    template <typename Real, integer N, typename Image_View>
    void minMax(
        const ConstView<N, Real, Image_View>& image,
        Real& min,
        Real& max)
    {
        min = Infinity();
        max = -Infinity();

        PackRange_::MinMaxFunctor<Real> minMaxFunctor(min, max);
        visit(image, minMaxFunctor);
    }

    template <typename Real, integer N, typename Image_View>
    void packRange(
        const View<N, Real, Image_View>& image,
        const NoDeduction<Real>& newMin,
        const NoDeduction<Real>& newMax)
    {
        ENSURE_OP(newMin, <=, newMax);

        Real minValue = 0;
        Real maxValue = 0;

        minMax(image, minValue, maxValue);

        Real valueDelta = maxValue - minValue;
        Real newValueDelta = newMax - newMin;
        if (valueDelta == 0 || newValueDelta == 0)
        {
            clear(newMax, image);
        }
        else
        {
            Real scale = newValueDelta / valueDelta;

            PackRange_::ScalingFunctor<Real> scalingFunctor(
                minValue, newMin, scale);

            visit(image, scalingFunctor);
        }
    }

}

#endif