2010-05-27 23:18:39 +00:00
|
|
|
// This code is in the public domain -- castanyo@yahoo.es
|
|
|
|
|
|
|
|
#ifndef NV_IMAGE_FLOATIMAGE_H
|
|
|
|
#define NV_IMAGE_FLOATIMAGE_H
|
|
|
|
|
|
|
|
#include "nvimage.h"
|
|
|
|
|
2011-09-27 05:17:01 +00:00
|
|
|
#include "nvmath/nvmath.h" // lerp
|
|
|
|
|
2010-05-27 23:18:39 +00:00
|
|
|
#include "nvcore/Debug.h"
|
|
|
|
#include "nvcore/Utils.h" // clamp
|
|
|
|
|
|
|
|
#include <stdlib.h> // abs
|
|
|
|
|
|
|
|
|
|
|
|
namespace nv
|
|
|
|
{
|
|
|
|
class Vector4;
|
|
|
|
class Matrix;
|
|
|
|
class Image;
|
|
|
|
class Filter;
|
|
|
|
class Kernel1;
|
|
|
|
class Kernel2;
|
|
|
|
class PolyphaseKernel;
|
|
|
|
|
|
|
|
/// Multicomponent floating point image class.
|
|
|
|
class FloatImage
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
enum WrapMode {
|
|
|
|
WrapMode_Clamp,
|
|
|
|
WrapMode_Repeat,
|
|
|
|
WrapMode_Mirror
|
|
|
|
};
|
|
|
|
|
2020-03-30 17:09:31 +00:00
|
|
|
FloatImage();
|
|
|
|
FloatImage(const FloatImage & img);
|
|
|
|
FloatImage(const Image * img);
|
|
|
|
~FloatImage();
|
2010-05-27 23:18:39 +00:00
|
|
|
|
|
|
|
/** @name Conversion. */
|
|
|
|
//@{
|
2020-03-30 17:09:31 +00:00
|
|
|
void initFrom(const Image * img);
|
|
|
|
Image * createImage(uint base_component = 0, uint num = 4) const;
|
|
|
|
Image * createImageGammaCorrect(float gamma = 2.2f) const;
|
2010-05-27 23:18:39 +00:00
|
|
|
//@}
|
|
|
|
|
|
|
|
/** @name Allocation. */
|
|
|
|
//@{
|
2020-03-30 17:09:31 +00:00
|
|
|
void allocate(uint c, uint w, uint h, uint d = 1);
|
|
|
|
void free(); // Does not clear members.
|
|
|
|
void resizeChannelCount(uint c);
|
2010-05-27 23:18:39 +00:00
|
|
|
//@}
|
|
|
|
|
|
|
|
/** @name Manipulation. */
|
|
|
|
//@{
|
2020-03-30 17:09:31 +00:00
|
|
|
void clear(float f = 0.0f);
|
|
|
|
void clear(uint component, float f = 0.0f);
|
|
|
|
void copyChannel(uint src, uint dst);
|
2010-05-27 23:18:39 +00:00
|
|
|
|
2020-03-30 17:09:31 +00:00
|
|
|
void normalize(uint base_component);
|
2010-05-27 23:18:39 +00:00
|
|
|
|
2020-03-30 17:09:31 +00:00
|
|
|
void packNormals(uint base_component);
|
|
|
|
void expandNormals(uint base_component);
|
|
|
|
void scaleBias(uint base_component, uint num, float scale, float add);
|
2010-05-27 23:18:39 +00:00
|
|
|
|
2020-03-30 17:09:31 +00:00
|
|
|
void clamp(uint base_component, uint num, float low, float high);
|
2010-05-27 23:18:39 +00:00
|
|
|
|
2020-03-30 17:09:31 +00:00
|
|
|
void toLinear(uint base_component, uint num, float gamma = 2.2f);
|
|
|
|
void toGamma(uint base_component, uint num, float gamma = 2.2f);
|
|
|
|
void exponentiate(uint base_component, uint num, float power);
|
2010-05-27 23:18:39 +00:00
|
|
|
|
2020-03-30 17:09:31 +00:00
|
|
|
void transform(uint base_component, const Matrix & m, const Vector4 & offset);
|
|
|
|
void swizzle(uint base_component, uint r, uint g, uint b, uint a);
|
2010-05-27 23:18:39 +00:00
|
|
|
|
2020-03-30 17:09:31 +00:00
|
|
|
FloatImage * fastDownSample() const;
|
|
|
|
FloatImage * downSample(const Filter & filter, WrapMode wm) const;
|
|
|
|
FloatImage * downSample(const Filter & filter, WrapMode wm, uint alpha) const;
|
|
|
|
FloatImage * resize(const Filter & filter, uint w, uint h, WrapMode wm) const;
|
|
|
|
FloatImage * resize(const Filter & filter, uint w, uint h, uint d, WrapMode wm) const;
|
|
|
|
FloatImage * resize(const Filter & filter, uint w, uint h, WrapMode wm, uint alpha) const;
|
|
|
|
FloatImage * resize(const Filter & filter, uint w, uint h, uint d, WrapMode wm, uint alpha) const;
|
2011-09-27 05:17:01 +00:00
|
|
|
|
2020-03-30 17:09:31 +00:00
|
|
|
void convolve(const Kernel2 & k, uint c, WrapMode wm);
|
2010-05-27 23:18:39 +00:00
|
|
|
|
2020-03-30 17:09:31 +00:00
|
|
|
//FloatImage * downSample(const Kernel1 & filter, WrapMode wm) const;
|
|
|
|
//FloatImage * downSample(const Kernel1 & filter, uint w, uint h, WrapMode wm) const;
|
2010-05-27 23:18:39 +00:00
|
|
|
//@}
|
|
|
|
|
2020-03-30 17:09:31 +00:00
|
|
|
float applyKernelXY(const Kernel2 * k, int x, int y, int z, uint c, WrapMode wm) const;
|
|
|
|
float applyKernelX(const Kernel1 * k, int x, int y, int z, uint c, WrapMode wm) const;
|
|
|
|
float applyKernelY(const Kernel1 * k, int x, int y, int z, uint c, WrapMode wm) const;
|
|
|
|
float applyKernelZ(const Kernel1 * k, int x, int y, int z, uint c, WrapMode wm) const;
|
|
|
|
void applyKernelX(const PolyphaseKernel & k, int y, int z, uint c, WrapMode wm, float * output) const;
|
|
|
|
void applyKernelY(const PolyphaseKernel & k, int x, int z, uint c, WrapMode wm, float * output, int output_stride) const;
|
|
|
|
void applyKernelZ(const PolyphaseKernel & k, int x, int y, uint c, WrapMode wm, float * output) const;
|
|
|
|
void applyKernelX(const PolyphaseKernel & k, int y, int z, uint c, uint a, WrapMode wm, float * output) const;
|
|
|
|
void applyKernelY(const PolyphaseKernel & k, int x, int z, uint c, uint a, WrapMode wm, float * output, int output_stride) const;
|
|
|
|
void applyKernelZ(const PolyphaseKernel & k, int x, int y, uint c, uint a, WrapMode wm, float * output) const;
|
2011-09-27 05:17:01 +00:00
|
|
|
|
2010-05-27 23:18:39 +00:00
|
|
|
|
2020-03-30 17:09:31 +00:00
|
|
|
void flipX();
|
|
|
|
void flipY();
|
|
|
|
void flipZ();
|
2010-05-28 23:16:06 +00:00
|
|
|
|
2020-03-30 17:09:31 +00:00
|
|
|
float alphaTestCoverage(float alphaRef, int alphaChannel, float alphaScale = 1.0f) const;
|
|
|
|
void scaleAlphaToCoverage(float coverage, float alphaRef, int alphaChannel);
|
2010-05-27 23:18:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
uint width() const { return m_width; }
|
|
|
|
uint height() const { return m_height; }
|
2011-09-27 05:17:01 +00:00
|
|
|
uint depth() const { return m_depth; }
|
|
|
|
uint componentCount() const { return m_componentCount; }
|
|
|
|
uint floatCount() const { return m_floatCount; }
|
|
|
|
uint pixelCount() const { return m_pixelCount; }
|
2010-05-27 23:18:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
/** @name Pixel access. */
|
|
|
|
//@{
|
|
|
|
const float * channel(uint c) const;
|
|
|
|
float * channel(uint c);
|
|
|
|
|
2011-09-27 05:17:01 +00:00
|
|
|
const float * plane(uint c, uint z) const;
|
|
|
|
float * plane(uint c, uint z);
|
|
|
|
|
|
|
|
const float * scanline(uint c, uint y, uint z) const;
|
|
|
|
float * scanline(uint c, uint y, uint z);
|
2010-05-27 23:18:39 +00:00
|
|
|
|
2011-09-27 05:17:01 +00:00
|
|
|
//float pixel(uint c, uint x, uint y) const;
|
|
|
|
//float & pixel(uint c, uint x, uint y);
|
2010-05-27 23:18:39 +00:00
|
|
|
|
2011-09-27 05:17:01 +00:00
|
|
|
float pixel(uint c, uint x, uint y, uint z) const;
|
|
|
|
float & pixel(uint c, uint x, uint y, uint z);
|
|
|
|
|
|
|
|
float pixel(uint c, uint idx) const;
|
|
|
|
float & pixel(uint c, uint idx);
|
2010-11-09 03:38:03 +00:00
|
|
|
|
2010-05-27 23:18:39 +00:00
|
|
|
float pixel(uint idx) const;
|
|
|
|
float & pixel(uint idx);
|
|
|
|
|
2011-09-27 05:17:01 +00:00
|
|
|
float sampleNearest(uint c, float x, float y, WrapMode wm) const;
|
|
|
|
float sampleLinear(uint c, float x, float y, WrapMode wm) const;
|
|
|
|
|
|
|
|
float sampleNearest(uint c, float x, float y, float z, WrapMode wm) const;
|
|
|
|
float sampleLinear(uint c, float x, float y, float z, WrapMode wm) const;
|
|
|
|
|
|
|
|
float sampleNearestClamp(uint c, float x, float y) const;
|
|
|
|
float sampleNearestRepeat(uint c, float x, float y) const;
|
|
|
|
float sampleNearestMirror(uint c, float x, float y) const;
|
2010-05-27 23:18:39 +00:00
|
|
|
|
2011-09-27 05:17:01 +00:00
|
|
|
float sampleNearestClamp(uint c, float x, float y, float z) const;
|
|
|
|
float sampleNearestRepeat(uint c, float x, float y, float z) const;
|
|
|
|
float sampleNearestMirror(uint c, float x, float y, float z) const;
|
2010-05-27 23:18:39 +00:00
|
|
|
|
2011-09-27 05:17:01 +00:00
|
|
|
float sampleLinearClamp(uint c, float x, float y) const;
|
|
|
|
float sampleLinearRepeat(uint c, float x, float y) const;
|
|
|
|
float sampleLinearMirror(uint c, float x, float y) const;
|
|
|
|
|
|
|
|
float sampleLinearClamp(uint c, float x, float y, float z) const;
|
|
|
|
float sampleLinearRepeat(uint c, float x, float y, float z) const;
|
|
|
|
float sampleLinearMirror(uint c, float x, float y, float z) const;
|
2010-05-27 23:18:39 +00:00
|
|
|
//@}
|
|
|
|
|
|
|
|
|
|
|
|
FloatImage* clone() const;
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
2011-09-27 05:17:01 +00:00
|
|
|
uint index(uint x, uint y, uint z) const;
|
|
|
|
uint indexClamp(int x, int y, int z) const;
|
|
|
|
uint indexRepeat(int x, int y, int z) const;
|
|
|
|
uint indexMirror(int x, int y, int z) const;
|
|
|
|
uint index(int x, int y, int z, WrapMode wm) const;
|
|
|
|
|
|
|
|
float bilerp(uint c, int ix0, int iy0, int ix1, int iy1, float fx, float fy) const;
|
|
|
|
float trilerp(uint c, int ix0, int iy0, int iz0, int ix1, int iy1, int iz1, float fx, float fy, float fz) const;
|
2010-05-27 23:18:39 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
|
2011-09-27 05:17:01 +00:00
|
|
|
uint16 m_componentCount;
|
|
|
|
uint16 m_width;
|
|
|
|
uint16 m_height;
|
|
|
|
uint16 m_depth;
|
|
|
|
uint32 m_pixelCount;
|
|
|
|
uint32 m_floatCount;
|
2010-05-27 23:18:39 +00:00
|
|
|
float * m_mem;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/// Get const channel pointer.
|
|
|
|
inline const float * FloatImage::channel(uint c) const
|
|
|
|
{
|
|
|
|
nvDebugCheck(m_mem != NULL);
|
2011-09-27 05:17:01 +00:00
|
|
|
nvDebugCheck(c < m_componentCount);
|
|
|
|
return m_mem + c * m_pixelCount;
|
2010-05-27 23:18:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Get channel pointer.
|
|
|
|
inline float * FloatImage::channel(uint c) {
|
|
|
|
nvDebugCheck(m_mem != NULL);
|
2011-09-27 05:17:01 +00:00
|
|
|
nvDebugCheck(c < m_componentCount);
|
|
|
|
return m_mem + c * m_pixelCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline const float * FloatImage::plane(uint c, uint z) const {
|
|
|
|
nvDebugCheck(z < m_depth);
|
|
|
|
return channel(c) + z * m_width * m_height;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline float * FloatImage::plane(uint c, uint z) {
|
|
|
|
nvDebugCheck(z < m_depth);
|
|
|
|
return channel(c) + z * m_width * m_height;
|
2010-05-27 23:18:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Get const scanline pointer.
|
2011-09-27 05:17:01 +00:00
|
|
|
inline const float * FloatImage::scanline(uint c, uint y, uint z) const
|
2010-05-27 23:18:39 +00:00
|
|
|
{
|
|
|
|
nvDebugCheck(y < m_height);
|
2011-09-27 05:17:01 +00:00
|
|
|
return plane(c, z) + y * m_width;
|
2010-05-27 23:18:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Get scanline pointer.
|
2011-10-01 02:07:32 +00:00
|
|
|
inline float * FloatImage::scanline(uint c, uint y, uint z)
|
2010-05-27 23:18:39 +00:00
|
|
|
{
|
|
|
|
nvDebugCheck(y < m_height);
|
2011-09-27 05:17:01 +00:00
|
|
|
return plane(c, z) + y * m_width;
|
2010-05-27 23:18:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Get pixel component.
|
2011-09-27 05:17:01 +00:00
|
|
|
inline float FloatImage::pixel(uint c, uint x, uint y, uint z) const
|
2010-05-27 23:18:39 +00:00
|
|
|
{
|
|
|
|
nvDebugCheck(m_mem != NULL);
|
2011-09-27 05:17:01 +00:00
|
|
|
nvDebugCheck(c < m_componentCount);
|
2010-05-27 23:18:39 +00:00
|
|
|
nvDebugCheck(x < m_width);
|
|
|
|
nvDebugCheck(y < m_height);
|
2011-09-27 05:17:01 +00:00
|
|
|
nvDebugCheck(z < m_depth);
|
2011-10-10 20:24:12 +00:00
|
|
|
return m_mem[c * m_pixelCount + index(x, y, z)];
|
2010-05-27 23:18:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Get pixel component.
|
2011-09-27 05:17:01 +00:00
|
|
|
inline float & FloatImage::pixel(uint c, uint x, uint y, uint z)
|
2010-05-27 23:18:39 +00:00
|
|
|
{
|
|
|
|
nvDebugCheck(m_mem != NULL);
|
2011-09-27 05:17:01 +00:00
|
|
|
nvDebugCheck(c < m_componentCount);
|
2010-05-27 23:18:39 +00:00
|
|
|
nvDebugCheck(x < m_width);
|
|
|
|
nvDebugCheck(y < m_height);
|
2011-09-27 05:17:01 +00:00
|
|
|
nvDebugCheck(z < m_depth);
|
2011-10-10 20:24:12 +00:00
|
|
|
return m_mem[c * m_pixelCount + index(x, y, z)];
|
2010-05-27 23:18:39 +00:00
|
|
|
}
|
|
|
|
|
2010-11-09 03:38:03 +00:00
|
|
|
/// Get pixel component.
|
2011-09-27 05:17:01 +00:00
|
|
|
inline float FloatImage::pixel(uint c, uint idx) const
|
2010-11-09 03:38:03 +00:00
|
|
|
{
|
|
|
|
nvDebugCheck(m_mem != NULL);
|
2011-09-27 05:17:01 +00:00
|
|
|
nvDebugCheck(c < m_componentCount);
|
|
|
|
nvDebugCheck(idx < m_pixelCount);
|
2011-10-10 20:24:12 +00:00
|
|
|
return m_mem[c * m_pixelCount + idx];
|
2010-11-09 03:38:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Get pixel component.
|
2011-09-27 05:17:01 +00:00
|
|
|
inline float & FloatImage::pixel(uint c, uint idx)
|
2010-11-09 03:38:03 +00:00
|
|
|
{
|
|
|
|
nvDebugCheck(m_mem != NULL);
|
2011-09-27 05:17:01 +00:00
|
|
|
nvDebugCheck(c < m_componentCount);
|
|
|
|
nvDebugCheck(idx < m_pixelCount);
|
2011-10-10 20:24:12 +00:00
|
|
|
return m_mem[c * m_pixelCount + idx];
|
2010-11-09 03:38:03 +00:00
|
|
|
}
|
|
|
|
|
2010-05-27 23:18:39 +00:00
|
|
|
/// Get pixel component.
|
|
|
|
inline float FloatImage::pixel(uint idx) const
|
|
|
|
{
|
2011-09-27 05:17:01 +00:00
|
|
|
nvDebugCheck(m_mem != NULL);
|
|
|
|
nvDebugCheck(idx < m_floatCount);
|
2010-05-27 23:18:39 +00:00
|
|
|
return m_mem[idx];
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Get pixel component.
|
|
|
|
inline float & FloatImage::pixel(uint idx)
|
|
|
|
{
|
2011-09-27 05:17:01 +00:00
|
|
|
nvDebugCheck(m_mem != NULL);
|
|
|
|
nvDebugCheck(idx < m_floatCount);
|
2010-05-27 23:18:39 +00:00
|
|
|
return m_mem[idx];
|
|
|
|
}
|
|
|
|
|
2011-09-27 05:17:01 +00:00
|
|
|
inline uint FloatImage::index(uint x, uint y, uint z) const
|
2010-05-27 23:18:39 +00:00
|
|
|
{
|
|
|
|
nvDebugCheck(x < m_width);
|
|
|
|
nvDebugCheck(y < m_height);
|
2011-09-27 05:17:01 +00:00
|
|
|
nvDebugCheck(z < m_depth);
|
2011-10-10 20:24:12 +00:00
|
|
|
uint idx = (z * m_height + y) * m_width + x;
|
|
|
|
nvDebugCheck(idx < m_pixelCount);
|
|
|
|
return idx;
|
2010-05-27 23:18:39 +00:00
|
|
|
}
|
|
|
|
|
2011-09-27 05:17:01 +00:00
|
|
|
|
|
|
|
inline int wrapClamp(int x, int w)
|
|
|
|
{
|
|
|
|
return nv::clamp(x, 0, w - 1);
|
|
|
|
}
|
|
|
|
inline int wrapRepeat(int x, int w)
|
2010-05-27 23:18:39 +00:00
|
|
|
{
|
2011-09-27 05:17:01 +00:00
|
|
|
if (x >= 0) return x % w;
|
|
|
|
else return (x + 1) % w + w - 1;
|
2010-05-27 23:18:39 +00:00
|
|
|
}
|
2011-09-27 05:17:01 +00:00
|
|
|
inline int wrapMirror(int x, int w)
|
|
|
|
{
|
|
|
|
if (w == 1) x = 0;
|
2010-05-27 23:18:39 +00:00
|
|
|
|
2011-09-27 05:17:01 +00:00
|
|
|
x = abs(x);
|
|
|
|
while (x >= w) {
|
|
|
|
x = abs(w + w - x - 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
return x;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline uint FloatImage::indexClamp(int x, int y, int z) const
|
2010-05-27 23:18:39 +00:00
|
|
|
{
|
2011-09-30 01:52:27 +00:00
|
|
|
x = wrapClamp(x, m_width);
|
|
|
|
y = wrapClamp(y, m_height);
|
|
|
|
z = wrapClamp(z, m_depth);
|
2011-09-27 05:17:01 +00:00
|
|
|
return index(x, y, z);
|
2010-05-27 23:18:39 +00:00
|
|
|
}
|
|
|
|
|
2011-09-27 05:17:01 +00:00
|
|
|
|
|
|
|
inline uint FloatImage::indexRepeat(int x, int y, int z) const
|
2010-05-27 23:18:39 +00:00
|
|
|
{
|
2011-09-27 05:17:01 +00:00
|
|
|
x = wrapRepeat(x, m_width);
|
|
|
|
y = wrapRepeat(y, m_height);
|
|
|
|
z = wrapRepeat(z, m_depth);
|
|
|
|
return index(x, y, z);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline uint FloatImage::indexMirror(int x, int y, int z) const
|
|
|
|
{
|
|
|
|
x = wrapMirror(x, m_width);
|
|
|
|
y = wrapMirror(y, m_height);
|
|
|
|
z = wrapMirror(z, m_depth);
|
|
|
|
return index(x, y, z);
|
2010-05-27 23:18:39 +00:00
|
|
|
}
|
|
|
|
|
2011-09-27 05:17:01 +00:00
|
|
|
inline uint FloatImage::index(int x, int y, int z, WrapMode wm) const
|
2010-05-27 23:18:39 +00:00
|
|
|
{
|
2011-09-27 05:17:01 +00:00
|
|
|
if (wm == WrapMode_Clamp) return indexClamp(x, y, z);
|
|
|
|
if (wm == WrapMode_Repeat) return indexRepeat(x, y, z);
|
|
|
|
/*if (wm == WrapMode_Mirror)*/ return indexMirror(x, y, z);
|
|
|
|
}
|
2010-05-27 23:18:39 +00:00
|
|
|
|
2011-09-27 05:17:01 +00:00
|
|
|
inline float FloatImage::bilerp(uint c, int ix0, int iy0, int ix1, int iy1, float fx, float fy) const {
|
|
|
|
int iz = 0;
|
|
|
|
float f1 = pixel(c, ix0, iy0, iz);
|
|
|
|
float f2 = pixel(c, ix1, iy0, iz);
|
|
|
|
float f3 = pixel(c, ix0, iy1, iz);
|
|
|
|
float f4 = pixel(c, ix1, iy1, iz);
|
2010-05-27 23:18:39 +00:00
|
|
|
|
2011-09-27 05:17:01 +00:00
|
|
|
float i1 = lerp(f1, f2, fx);
|
|
|
|
float i2 = lerp(f3, f4, fx);
|
2010-05-27 23:18:39 +00:00
|
|
|
|
2011-09-27 05:17:01 +00:00
|
|
|
return lerp(i1, i2, fy);
|
|
|
|
}
|
2010-05-27 23:18:39 +00:00
|
|
|
|
2011-09-27 05:17:01 +00:00
|
|
|
inline float FloatImage::trilerp(uint c, int ix0, int iy0, int iz0, int ix1, int iy1, int iz1, float fx, float fy, float fz) const {
|
|
|
|
float f000 = pixel(c, ix0, iy0, iz0);
|
|
|
|
float f100 = pixel(c, ix1, iy0, iz0);
|
|
|
|
float f010 = pixel(c, ix0, iy1, iz0);
|
|
|
|
float f110 = pixel(c, ix1, iy1, iz0);
|
|
|
|
float f001 = pixel(c, ix0, iy0, iz1);
|
|
|
|
float f101 = pixel(c, ix1, iy0, iz1);
|
|
|
|
float f011 = pixel(c, ix0, iy1, iz1);
|
|
|
|
float f111 = pixel(c, ix1, iy1, iz1);
|
|
|
|
|
|
|
|
float i1 = lerp(f000, f001, fz);
|
|
|
|
float i2 = lerp(f010, f011, fz);
|
|
|
|
float j1 = lerp(f100, f101, fz);
|
|
|
|
float j2 = lerp(f110, f111, fz);
|
|
|
|
|
|
|
|
float w1 = lerp(i1, i2, fy);
|
|
|
|
float w2 = lerp(j1, j2, fy);
|
|
|
|
|
|
|
|
return lerp(w1, w2, fx);
|
2010-05-27 23:18:39 +00:00
|
|
|
}
|
|
|
|
|
2011-09-27 05:17:01 +00:00
|
|
|
// Does not compare channel count.
|
|
|
|
inline bool sameLayout(const FloatImage * img0, const FloatImage * img1) {
|
|
|
|
if (img0 == NULL || img1 == NULL) return false;
|
|
|
|
return img0->width() == img1->width() && img0->height() == img1->height() && img0->depth() == img1->depth();
|
2010-05-27 23:18:39 +00:00
|
|
|
}
|
|
|
|
|
2011-09-27 05:17:01 +00:00
|
|
|
|
2010-05-27 23:18:39 +00:00
|
|
|
} // nv namespace
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endif // NV_IMAGE_FLOATIMAGE_H
|