Files
UnrealEngine/Engine/Source/ThirdParty/openexr/openexr-3.3.2/Contrib/DtexToExr/PxDeepOutRow.h
2025-05-18 13:04:45 +08:00

237 lines
6.9 KiB
C++

//
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) Contributors to the OpenEXR Project.
//
#ifndef _PxDeepOutRow_h_
#define _PxDeepOutRow_h_
#include "PxDeepOutPixel.h"
#include "PxDeepUtils.h"
#include <ImfChannelList.h>
#include <ImfDeepFrameBuffer.h>
#include <ImfDeepScanLineOutputFile.h>
#include <ImfPartType.h>
namespace PxDeep
{
//-*****************************************************************************
//-*****************************************************************************
// DEEP OUT ROW
//-*****************************************************************************
//-*****************************************************************************
template <typename RGBA_T> class DeepOutRow
{
public:
DeepOutRow (int i_width, bool i_doDeepBack, bool i_doRGB);
void clear ();
void addHole (int i_x) { m_sampleCounts[i_x] = 0; }
void addPixel (int i_x, const DeepOutPixel<RGBA_T>& i_pixel);
void setFrameBuffer (Imf::DeepFrameBuffer& o_frameBuffer);
protected:
// Width of the row.
int m_width;
// Whether or not to bother with deep back
bool m_doDeepBack;
// Whether or not to bother with RGB
bool m_doRGB;
// Scanline sample buffers.
std::vector<uint> m_sampleCounts;
// The pointers to data at each pixel
std::vector<float*> m_deepFrontPtrs;
std::vector<float*> m_deepBackPtrs;
std::vector<RGBA_T*> m_redPtrs;
std::vector<RGBA_T*> m_greenPtrs;
std::vector<RGBA_T*> m_bluePtrs;
std::vector<RGBA_T*> m_alphaPtrs;
// The data itself.
std::vector<float> m_deepFrontSamples;
std::vector<float> m_deepBackSamples;
std::vector<RGBA_T> m_redSamples;
std::vector<RGBA_T> m_greenSamples;
std::vector<RGBA_T> m_blueSamples;
std::vector<RGBA_T> m_alphaSamples;
};
//-*****************************************************************************
template <typename T>
inline void
VecAppend (T& i_dst, const T& i_src)
{
i_dst.insert (i_dst.end (), i_src.begin (), i_src.end ());
}
//-*****************************************************************************
template <typename RGBA_T>
DeepOutRow<RGBA_T>::DeepOutRow (int i_width, bool i_doDeepBack, bool i_doRGB)
: m_width (i_width), m_doDeepBack (i_doDeepBack), m_doRGB (i_doRGB)
{
m_sampleCounts.resize ((size_t) m_width);
m_deepFrontPtrs.resize ((size_t) m_width);
if (m_doDeepBack) { m_deepBackPtrs.resize ((size_t) m_width); }
if (m_doRGB)
{
m_redPtrs.resize ((size_t) m_width);
m_greenPtrs.resize ((size_t) m_width);
m_bluePtrs.resize ((size_t) m_width);
}
m_alphaPtrs.resize ((size_t) m_width);
}
//-*****************************************************************************
template <typename RGBA_T>
void
DeepOutRow<RGBA_T>::clear ()
{
std::fill (m_sampleCounts.begin (), m_sampleCounts.end (), (uint) 0);
m_deepFrontSamples.clear ();
m_deepBackSamples.clear ();
m_redSamples.clear ();
m_greenSamples.clear ();
m_blueSamples.clear ();
m_alphaSamples.clear ();
}
//-*****************************************************************************
template <typename RGBA_T>
void
DeepOutRow<RGBA_T>::addPixel (int i_x, const DeepOutPixel<RGBA_T>& i_pixel)
{
int npoints = i_pixel.size ();
m_sampleCounts[i_x] = npoints;
if (npoints > 0)
{
VecAppend (m_deepFrontSamples, i_pixel.deepFront);
if (m_doDeepBack) { VecAppend (m_deepBackSamples, i_pixel.deepBack); }
if (m_doRGB)
{
VecAppend (m_redSamples, i_pixel.red);
VecAppend (m_greenSamples, i_pixel.green);
VecAppend (m_blueSamples, i_pixel.blue);
}
VecAppend (m_alphaSamples, i_pixel.alpha);
}
}
//-*****************************************************************************
template <typename RGBA_T>
void
DeepOutRow<RGBA_T>::setFrameBuffer (Imf::DeepFrameBuffer& o_frameBuffer)
{
// Set up the pointers.
float* deepFrontLastPtr = m_deepFrontSamples.data ();
float* deepBackLastPtr = m_deepBackSamples.data ();
RGBA_T* redLastPtr = m_redSamples.data ();
RGBA_T* greenLastPtr = m_greenSamples.data ();
RGBA_T* blueLastPtr = m_blueSamples.data ();
RGBA_T* alphaLastPtr = m_alphaSamples.data ();
for (int x = 0; x < m_width; ++x)
{
m_deepFrontPtrs[x] = deepFrontLastPtr;
if (m_doDeepBack) { m_deepBackPtrs[x] = deepBackLastPtr; }
if (m_doRGB)
{
m_redPtrs[x] = redLastPtr;
m_greenPtrs[x] = greenLastPtr;
m_bluePtrs[x] = blueLastPtr;
}
m_alphaPtrs[x] = alphaLastPtr;
int c = m_sampleCounts[x];
deepFrontLastPtr += c;
deepBackLastPtr += c;
redLastPtr += c;
greenLastPtr += c;
blueLastPtr += c;
alphaLastPtr += c;
}
// Sample counts
o_frameBuffer.insertSampleCountSlice (Imf::Slice (
Imf::UINT,
(char*) m_sampleCounts.data (),
sizeof (uint), // x stride
0)); // y stride
// RGB
if (m_doRGB)
{
o_frameBuffer.insert (
"R",
Imf::DeepSlice (
ImfPixelType<RGBA_T> (),
(char*) m_redPtrs.data (),
sizeof (RGBA_T*), // xstride
0, // ystride
sizeof (RGBA_T))); // sample stride
o_frameBuffer.insert (
"G",
Imf::DeepSlice (
ImfPixelType<RGBA_T> (),
(char*) m_greenPtrs.data (),
sizeof (RGBA_T*), // xstride
0, // ystride
sizeof (RGBA_T))); // sample stride
o_frameBuffer.insert (
"B",
Imf::DeepSlice (
ImfPixelType<RGBA_T> (),
(char*) m_bluePtrs.data (),
sizeof (RGBA_T*), // xstride
0, // ystride
sizeof (RGBA_T))); // sample stride
}
// ALPHA
o_frameBuffer.insert (
"A",
Imf::DeepSlice (
ImfPixelType<RGBA_T> (),
(char*) m_alphaPtrs.data (),
sizeof (RGBA_T*), // xstride
0, // ystride
sizeof (RGBA_T))); // sample stride
// DEEP FRONT
o_frameBuffer.insert (
"Z",
Imf::DeepSlice (
Imf::FLOAT,
(char*) m_deepFrontPtrs.data (),
sizeof (float*), // xstride
0, // ystride
sizeof (float))); // sample stride
// DEEP BACK
if (m_doDeepBack)
{
o_frameBuffer.insert (
"ZBack",
Imf::DeepSlice (
Imf::FLOAT,
(char*) m_deepBackPtrs.data (),
sizeof (float*), // xstride
0, // ystride
sizeof (float))); // sample stride
}
}
} // End namespace PxDeep
#endif