156 lines
3.7 KiB
C++
156 lines
3.7 KiB
C++
//
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
// Copyright (c) Contributors to the OpenEXR Project.
|
|
//
|
|
|
|
#ifndef INCLUDED_IMF_LUT_H
|
|
#define INCLUDED_IMF_LUT_H
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Lookup tables for efficient application
|
|
// of half --> half functions to pixel data,
|
|
// and some commonly applied functions.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include "ImfExport.h"
|
|
#include "ImfNamespace.h"
|
|
|
|
#include "ImfRgbaFile.h"
|
|
|
|
#include <ImathBox.h>
|
|
#include <halfFunction.h>
|
|
|
|
OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
|
|
|
|
//
|
|
// Lookup table for individual half channels.
|
|
//
|
|
|
|
class HalfLut
|
|
{
|
|
public:
|
|
//------------
|
|
// Constructor
|
|
//------------
|
|
|
|
template <class Function> HalfLut (Function f);
|
|
|
|
//----------------------------------------------------------------------
|
|
// Apply the table to data[0], data[stride] ... data[(nData-1) * stride]
|
|
//----------------------------------------------------------------------
|
|
|
|
IMF_EXPORT
|
|
void apply (half* data, int nData, int stride = 1) const;
|
|
|
|
//---------------------------------------------------------------
|
|
// Apply the table to a frame buffer slice (see ImfFrameBuffer.h)
|
|
//---------------------------------------------------------------
|
|
|
|
IMF_EXPORT
|
|
void
|
|
apply (const Slice& data, const IMATH_NAMESPACE::Box2i& dataWindow) const;
|
|
|
|
private:
|
|
halfFunction<half> _lut;
|
|
};
|
|
|
|
//
|
|
// Lookup table for combined RGBA data.
|
|
//
|
|
|
|
class RgbaLut
|
|
{
|
|
public:
|
|
//------------
|
|
// Constructor
|
|
//------------
|
|
|
|
template <class Function>
|
|
RgbaLut (Function f, RgbaChannels chn = WRITE_RGB);
|
|
|
|
//----------------------------------------------------------------------
|
|
// Apply the table to data[0], data[stride] ... data[(nData-1) * stride]
|
|
//----------------------------------------------------------------------
|
|
|
|
IMF_EXPORT
|
|
void apply (Rgba* data, int nData, int stride = 1) const;
|
|
|
|
//-----------------------------------------------------------------------
|
|
// Apply the table to a frame buffer (see RgbaOutpuFile.setFrameBuffer())
|
|
//-----------------------------------------------------------------------
|
|
|
|
IMF_EXPORT
|
|
void apply (
|
|
Rgba* base,
|
|
int xStride,
|
|
int yStride,
|
|
const IMATH_NAMESPACE::Box2i& dataWindow) const;
|
|
|
|
private:
|
|
halfFunction<half> _lut;
|
|
RgbaChannels _chn;
|
|
};
|
|
|
|
//
|
|
// 12bit log rounding reduces data to 20 stops with 200 steps per stop.
|
|
// That makes 4000 numbers. An extra 96 just come along for the ride.
|
|
// Zero explicitly remains zero. The first non-zero half will map to 1
|
|
// in the 0-4095 12log space. A nice power of two number is placed at
|
|
// the center [2000] and that number is near 0.18.
|
|
//
|
|
|
|
IMF_EXPORT
|
|
half round12log (half x);
|
|
|
|
//
|
|
// Round to n-bit precision (n should be between 0 and 10).
|
|
// After rounding, the significand's 10-n least significant
|
|
// bits will be zero.
|
|
//
|
|
|
|
struct roundNBit
|
|
{
|
|
roundNBit (int n) : n (n) {}
|
|
half operator() (half x) { return x.round (n); }
|
|
int n;
|
|
};
|
|
|
|
//
|
|
// Template definitions
|
|
//
|
|
|
|
template <class Function>
|
|
HalfLut::HalfLut (Function f)
|
|
: _lut (
|
|
f,
|
|
-HALF_MAX,
|
|
HALF_MAX,
|
|
half (0),
|
|
half::posInf (),
|
|
half::negInf (),
|
|
half::qNan ())
|
|
{
|
|
// empty
|
|
}
|
|
|
|
template <class Function>
|
|
RgbaLut::RgbaLut (Function f, RgbaChannels chn)
|
|
: _lut (
|
|
f,
|
|
-HALF_MAX,
|
|
HALF_MAX,
|
|
half (0),
|
|
half::posInf (),
|
|
half::negInf (),
|
|
half::qNan ())
|
|
, _chn (chn)
|
|
{
|
|
// empty
|
|
}
|
|
|
|
OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
|
|
|
|
#endif
|