debugging..
parent
ee5b29878f
commit
8d84d0b1a0
|
@ -678,12 +678,17 @@ public:
|
||||||
* specified component format. Names for each of the resulting channels should
|
* specified component format. Names for each of the resulting channels should
|
||||||
* be provided via the \c channelNames parameters.
|
* be provided via the \c channelNames parameters.
|
||||||
*
|
*
|
||||||
* This function is currently only used by the \c hdrfilm plugin but located here
|
* This feature is currently used by the \c hdrfilm and \c tiledhdrfilm plugins.
|
||||||
* as it is tied to the internals of this class.
|
|
||||||
*/
|
*/
|
||||||
ref<Bitmap> convertMultiSpectrumAlphaWeight(const std::vector<EPixelFormat> &pixelFormats,
|
ref<Bitmap> convertMultiSpectrumAlphaWeight(const std::vector<EPixelFormat> &pixelFormats,
|
||||||
EComponentFormat componentFormat, const std::vector<std::string> &channelNames) const;
|
EComponentFormat componentFormat, const std::vector<std::string> &channelNames) const;
|
||||||
|
|
||||||
|
/// Similar to the above, but writes to an already existing image
|
||||||
|
static void convertMultiSpectrumAlphaWeight(const Bitmap *source,
|
||||||
|
const uint8_t *sourcePtr, const Bitmap *target, uint8_t *targetPtr,
|
||||||
|
const std::vector<EPixelFormat> &pixelFormats,
|
||||||
|
EComponentFormat componentFormat, size_t count);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Apply Reinhard et al's tonemapper in chromaticity space
|
* \brief Apply Reinhard et al's tonemapper in chromaticity space
|
||||||
*
|
*
|
||||||
|
|
|
@ -215,7 +215,7 @@ public:
|
||||||
std::vector<std::string> pixelFormats = tokenize(boost::to_lower_copy(
|
std::vector<std::string> pixelFormats = tokenize(boost::to_lower_copy(
|
||||||
props.getString("pixelFormat", "rgb")), " ,");
|
props.getString("pixelFormat", "rgb")), " ,");
|
||||||
std::vector<std::string> channelNames = tokenize(
|
std::vector<std::string> channelNames = tokenize(
|
||||||
props.getString("channelNames", "rgb"), ", ");
|
props.getString("channelNames", ""), ", ");
|
||||||
std::string componentFormat = boost::to_lower_copy(
|
std::string componentFormat = boost::to_lower_copy(
|
||||||
props.getString("componentFormat", "float16"));
|
props.getString("componentFormat", "float16"));
|
||||||
|
|
||||||
|
@ -238,47 +238,50 @@ public:
|
||||||
|
|
||||||
for (size_t i=0; i<pixelFormats.size(); ++i) {
|
for (size_t i=0; i<pixelFormats.size(); ++i) {
|
||||||
std::string pixelFormat = pixelFormats[i];
|
std::string pixelFormat = pixelFormats[i];
|
||||||
std::string name = i < channelNames.size() ? channelNames[i] : "";
|
std::string name = i < channelNames.size() ? (channelNames[i] + std::string(".")) : "";
|
||||||
|
|
||||||
if (pixelFormat == "luminance") {
|
if (pixelFormat == "luminance") {
|
||||||
m_pixelFormats.push_back(Bitmap::ELuminance);
|
m_pixelFormats.push_back(Bitmap::ELuminance);
|
||||||
m_channelNames.push_back(name + ".Y");
|
m_channelNames.push_back(name + "Y");
|
||||||
} else if (pixelFormat == "luminancealpha") {
|
} else if (pixelFormat == "luminancealpha") {
|
||||||
m_pixelFormats.push_back(Bitmap::ELuminanceAlpha);
|
m_pixelFormats.push_back(Bitmap::ELuminanceAlpha);
|
||||||
m_channelNames.push_back(name + ".Y");
|
m_channelNames.push_back(name + "Y");
|
||||||
m_channelNames.push_back(name + ".A");
|
m_channelNames.push_back(name + "A");
|
||||||
} else if (pixelFormat == "rgb") {
|
} else if (pixelFormat == "rgb") {
|
||||||
m_pixelFormats.push_back(Bitmap::ERGB);
|
m_pixelFormats.push_back(Bitmap::ERGB);
|
||||||
m_channelNames.push_back(name + ".R");
|
m_channelNames.push_back(name + "R");
|
||||||
m_channelNames.push_back(name + ".G");
|
m_channelNames.push_back(name + "G");
|
||||||
m_channelNames.push_back(name + ".B");
|
m_channelNames.push_back(name + "B");
|
||||||
} else if (pixelFormat == "rgba") {
|
} else if (pixelFormat == "rgba") {
|
||||||
m_pixelFormats.push_back(Bitmap::ERGBA);
|
m_pixelFormats.push_back(Bitmap::ERGBA);
|
||||||
m_channelNames.push_back(name + ".R");
|
m_channelNames.push_back(name + "R");
|
||||||
m_channelNames.push_back(name + ".G");
|
m_channelNames.push_back(name + "G");
|
||||||
m_channelNames.push_back(name + ".B");
|
m_channelNames.push_back(name + "B");
|
||||||
m_channelNames.push_back(name + ".A");
|
m_channelNames.push_back(name + "A");
|
||||||
} else if (pixelFormat == "xyz") {
|
} else if (pixelFormat == "xyz") {
|
||||||
m_pixelFormats.push_back(Bitmap::EXYZ);
|
m_pixelFormats.push_back(Bitmap::EXYZ);
|
||||||
if (m_pixelFormats.size() > 1)
|
m_channelNames.push_back(name + "X");
|
||||||
Log(EError, "The XYZ pixel format is not supported for general multi-channel images!");
|
m_channelNames.push_back(name + "Y");
|
||||||
|
m_channelNames.push_back(name + "Z");
|
||||||
} else if (pixelFormat == "xyza") {
|
} else if (pixelFormat == "xyza") {
|
||||||
m_pixelFormats.push_back(Bitmap::EXYZA);
|
m_pixelFormats.push_back(Bitmap::EXYZA);
|
||||||
if (m_pixelFormats.size() > 1)
|
m_channelNames.push_back(name + "X");
|
||||||
Log(EError, "The XYZA pixel format is not supported for general multi-channel images!");
|
m_channelNames.push_back(name + "Y");
|
||||||
|
m_channelNames.push_back(name + "Z");
|
||||||
|
m_channelNames.push_back(name + "A");
|
||||||
} else if (pixelFormat == "spectrum") {
|
} else if (pixelFormat == "spectrum") {
|
||||||
m_pixelFormats.push_back(Bitmap::ESpectrum);
|
m_pixelFormats.push_back(Bitmap::ESpectrum);
|
||||||
for (int i=0; i<SPECTRUM_SAMPLES; ++i) {
|
for (int i=0; i<SPECTRUM_SAMPLES; ++i) {
|
||||||
std::pair<Float, Float> coverage = Spectrum::getBinCoverage(i);
|
std::pair<Float, Float> coverage = Spectrum::getBinCoverage(i);
|
||||||
m_channelNames.push_back(name + formatString(".%.2f-%.2fnm", coverage.first, coverage.second));
|
m_channelNames.push_back(name + formatString("%.2f-%.2fnm", coverage.first, coverage.second));
|
||||||
}
|
}
|
||||||
} else if (pixelFormat == "spectrumalpha") {
|
} else if (pixelFormat == "spectrumalpha") {
|
||||||
m_pixelFormats.push_back(Bitmap::ESpectrumAlpha);
|
m_pixelFormats.push_back(Bitmap::ESpectrumAlpha);
|
||||||
for (int i=0; i<SPECTRUM_SAMPLES; ++i) {
|
for (int i=0; i<SPECTRUM_SAMPLES; ++i) {
|
||||||
std::pair<Float, Float> coverage = Spectrum::getBinCoverage(i);
|
std::pair<Float, Float> coverage = Spectrum::getBinCoverage(i);
|
||||||
m_channelNames.push_back(name + formatString(".%.2f-%.2fnm", coverage.first, coverage.second));
|
m_channelNames.push_back(name + formatString("%.2f-%.2fnm", coverage.first, coverage.second));
|
||||||
}
|
}
|
||||||
m_channelNames.push_back(name + ".A");
|
m_channelNames.push_back(name + "A");
|
||||||
} else {
|
} else {
|
||||||
Log(EError, "The \"pixelFormat\" parameter must either be equal to "
|
Log(EError, "The \"pixelFormat\" parameter must either be equal to "
|
||||||
"\"luminance\", \"luminanceAlpha\", \"rgb\", \"rgba\", \"xyz\", \"xyza\", "
|
"\"luminance\", \"luminanceAlpha\", \"rgb\", \"rgba\", \"xyz\", \"xyza\", "
|
||||||
|
@ -529,13 +532,14 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasAlpha() const {
|
bool hasAlpha() const {
|
||||||
Assert(m_pixelFormats.size() > 0);
|
for (size_t i=0; i<m_pixelFormats.size(); ++i) {
|
||||||
return
|
if (m_pixelFormats[i] == Bitmap::ELuminanceAlpha ||
|
||||||
m_pixelFormats[0] == Bitmap::ELuminanceAlpha ||
|
m_pixelFormats[i] == Bitmap::ERGBA ||
|
||||||
m_pixelFormats[0] == Bitmap::ERGBA ||
|
m_pixelFormats[i] == Bitmap::EXYZA ||
|
||||||
m_pixelFormats[0] == Bitmap::EXYZA ||
|
m_pixelFormats[i] == Bitmap::ESpectrumAlpha)
|
||||||
m_pixelFormats[0] == Bitmap::ESpectrumAlpha ||
|
return true;
|
||||||
m_pixelFormats.size() > 1;
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool destinationExists(const fs::path &baseName) const {
|
bool destinationExists(const fs::path &baseName) const {
|
||||||
|
|
|
@ -101,37 +101,78 @@ MTS_NAMESPACE_BEGIN
|
||||||
class TiledHDRFilm : public Film {
|
class TiledHDRFilm : public Film {
|
||||||
public:
|
public:
|
||||||
TiledHDRFilm(const Properties &props) : Film(props), m_output(NULL), m_frameBuffer(NULL) {
|
TiledHDRFilm(const Properties &props) : Film(props), m_output(NULL), m_frameBuffer(NULL) {
|
||||||
std::string pixelFormat = boost::to_lower_copy(
|
std::vector<std::string> pixelFormats = tokenize(boost::to_lower_copy(
|
||||||
props.getString("pixelFormat", "rgb"));
|
props.getString("pixelFormat", "rgb")), " ,");
|
||||||
|
std::vector<std::string> channelNames = tokenize(
|
||||||
|
props.getString("channelNames", ""), ", ");
|
||||||
std::string componentFormat = boost::to_lower_copy(
|
std::string componentFormat = boost::to_lower_copy(
|
||||||
props.getString("componentFormat", "float16"));
|
props.getString("componentFormat", "float16"));
|
||||||
|
|
||||||
if (pixelFormat == "luminance") {
|
if (pixelFormats.empty())
|
||||||
m_pixelFormat = Bitmap::ELuminance;
|
Log(EError, "At least one pixel format must be specified!");
|
||||||
} else if (pixelFormat == "luminancealpha") {
|
|
||||||
m_pixelFormat = Bitmap::ELuminanceAlpha;
|
if (m_pixelFormats.size() != 1 && m_channelNames.size() != m_pixelFormats.size())
|
||||||
} else if (pixelFormat == "rgb") {
|
Log(EError, "Number of channel names must match the number of specified pixel formats!");
|
||||||
m_pixelFormat = Bitmap::ERGB;
|
|
||||||
} else if (pixelFormat == "rgba") {
|
for (size_t i=0; i<pixelFormats.size(); ++i) {
|
||||||
m_pixelFormat = Bitmap::ERGBA;
|
std::string pixelFormat = pixelFormats[i];
|
||||||
} else if (pixelFormat == "xyz") {
|
std::string name = i < channelNames.size() ? (channelNames[i] + std::string(".")) : "";
|
||||||
m_pixelFormat = Bitmap::EXYZ;
|
|
||||||
} else if (pixelFormat == "xyza") {
|
if (pixelFormat == "luminance") {
|
||||||
m_pixelFormat = Bitmap::EXYZA;
|
m_pixelFormats.push_back(Bitmap::ELuminance);
|
||||||
} else if (pixelFormat == "spectrum") {
|
m_channelNames.push_back(name + "Y");
|
||||||
m_pixelFormat = Bitmap::ESpectrum;
|
} else if (pixelFormat == "luminancealpha") {
|
||||||
} else if (pixelFormat == "spectrumalpha") {
|
m_pixelFormats.push_back(Bitmap::ELuminanceAlpha);
|
||||||
m_pixelFormat = Bitmap::ESpectrumAlpha;
|
m_channelNames.push_back(name + "Y");
|
||||||
} else {
|
m_channelNames.push_back(name + "A");
|
||||||
Log(EError, "The \"pixelFormat\" parameter must either be equal to "
|
} else if (pixelFormat == "rgb") {
|
||||||
"\"luminance\", \"luminanceAlpha\", \"rgb\", \"rgba\", \"xyz\", \"xyza\", "
|
m_pixelFormats.push_back(Bitmap::ERGB);
|
||||||
"\"spectrum\", or \"spectrumAlpha\"!");
|
m_channelNames.push_back(name + "R");
|
||||||
|
m_channelNames.push_back(name + "G");
|
||||||
|
m_channelNames.push_back(name + "B");
|
||||||
|
} else if (pixelFormat == "rgba") {
|
||||||
|
m_pixelFormats.push_back(Bitmap::ERGBA);
|
||||||
|
m_channelNames.push_back(name + "R");
|
||||||
|
m_channelNames.push_back(name + "G");
|
||||||
|
m_channelNames.push_back(name + "B");
|
||||||
|
m_channelNames.push_back(name + "A");
|
||||||
|
} else if (pixelFormat == "xyz") {
|
||||||
|
m_pixelFormats.push_back(Bitmap::EXYZ);
|
||||||
|
m_channelNames.push_back(name + "X");
|
||||||
|
m_channelNames.push_back(name + "Y");
|
||||||
|
m_channelNames.push_back(name + "Z");
|
||||||
|
} else if (pixelFormat == "xyza") {
|
||||||
|
m_pixelFormats.push_back(Bitmap::EXYZA);
|
||||||
|
m_channelNames.push_back(name + "X");
|
||||||
|
m_channelNames.push_back(name + "Y");
|
||||||
|
m_channelNames.push_back(name + "Z");
|
||||||
|
m_channelNames.push_back(name + "A");
|
||||||
|
} else if (pixelFormat == "spectrum") {
|
||||||
|
m_pixelFormats.push_back(Bitmap::ESpectrum);
|
||||||
|
for (int i=0; i<SPECTRUM_SAMPLES; ++i) {
|
||||||
|
std::pair<Float, Float> coverage = Spectrum::getBinCoverage(i);
|
||||||
|
m_channelNames.push_back(name + formatString("%.2f-%.2fnm", coverage.first, coverage.second));
|
||||||
|
}
|
||||||
|
} else if (pixelFormat == "spectrumalpha") {
|
||||||
|
m_pixelFormats.push_back(Bitmap::ESpectrumAlpha);
|
||||||
|
for (int i=0; i<SPECTRUM_SAMPLES; ++i) {
|
||||||
|
std::pair<Float, Float> coverage = Spectrum::getBinCoverage(i);
|
||||||
|
m_channelNames.push_back(name + formatString("%.2f-%.2fnm", coverage.first, coverage.second));
|
||||||
|
}
|
||||||
|
m_channelNames.push_back(name + "A");
|
||||||
|
} else {
|
||||||
|
Log(EError, "The \"pixelFormat\" parameter must either be equal to "
|
||||||
|
"\"luminance\", \"luminanceAlpha\", \"rgb\", \"rgba\", \"xyz\", \"xyza\", "
|
||||||
|
"\"spectrum\", or \"spectrumAlpha\"!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SPECTRUM_SAMPLES == 3 && (m_pixelFormat == Bitmap::ESpectrum || m_pixelFormat == Bitmap::ESpectrumAlpha))
|
for (size_t i=0; i<m_pixelFormats.size(); ++i) {
|
||||||
Log(EError, "You requested to render a spectral image, but Mitsuba is currently "
|
if (SPECTRUM_SAMPLES == 3 && (m_pixelFormats[i] == Bitmap::ESpectrum || m_pixelFormats[i] == Bitmap::ESpectrumAlpha))
|
||||||
"configured for a RGB flow (i.e. SPECTRUM_SAMPLES = 3). You will need to recompile "
|
Log(EError, "You requested to render a spectral image, but Mitsuba is currently "
|
||||||
"it with a different configuration. Please see the documentation for details.");
|
"configured for a RGB flow (i.e. SPECTRUM_SAMPLES = 3). You will need to recompile "
|
||||||
|
"it with a different configuration. Please see the documentation for details.");
|
||||||
|
}
|
||||||
|
|
||||||
if (componentFormat == "float16") {
|
if (componentFormat == "float16") {
|
||||||
m_componentFormat = Bitmap::EFloat16;
|
m_componentFormat = Bitmap::EFloat16;
|
||||||
|
@ -151,7 +192,12 @@ public:
|
||||||
|
|
||||||
TiledHDRFilm(Stream *stream, InstanceManager *manager)
|
TiledHDRFilm(Stream *stream, InstanceManager *manager)
|
||||||
: Film(stream, manager), m_output(NULL), m_frameBuffer(NULL) {
|
: Film(stream, manager), m_output(NULL), m_frameBuffer(NULL) {
|
||||||
m_pixelFormat = (Bitmap::EPixelFormat) stream->readUInt();
|
m_pixelFormats.resize((size_t) stream->readUInt());
|
||||||
|
for (size_t i=0; i<m_pixelFormats.size(); ++i)
|
||||||
|
m_pixelFormats[i] = (Bitmap::EPixelFormat) stream->readUInt();
|
||||||
|
m_channelNames.resize((size_t) stream->readUInt());
|
||||||
|
for (size_t i=0; i<m_channelNames.size(); ++i)
|
||||||
|
m_channelNames[i] = stream->readString();
|
||||||
m_componentFormat = (Bitmap::EComponentFormat) stream->readUInt();
|
m_componentFormat = (Bitmap::EComponentFormat) stream->readUInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,7 +207,11 @@ public:
|
||||||
|
|
||||||
void serialize(Stream *stream, InstanceManager *manager) const {
|
void serialize(Stream *stream, InstanceManager *manager) const {
|
||||||
Film::serialize(stream, manager);
|
Film::serialize(stream, manager);
|
||||||
stream->writeUInt(m_pixelFormat);
|
for (size_t i=0; i<m_pixelFormats.size(); ++i)
|
||||||
|
stream->writeUInt(m_pixelFormats[i]);
|
||||||
|
stream->writeUInt((uint32_t) m_channelNames.size());
|
||||||
|
for (size_t i=0; i<m_channelNames.size(); ++i)
|
||||||
|
stream->writeString(m_channelNames[i]);
|
||||||
stream->writeUInt(m_componentFormat);
|
stream->writeUInt(m_componentFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,15 +219,6 @@ public:
|
||||||
if (m_output)
|
if (m_output)
|
||||||
develop(NULL, 0);
|
develop(NULL, 0);
|
||||||
|
|
||||||
Bitmap::EPixelFormat pixelFormat = m_pixelFormat;
|
|
||||||
#if SPECTRUM_SAMPLES == 3
|
|
||||||
if (pixelFormat == Bitmap::ESpectrum)
|
|
||||||
pixelFormat = Bitmap::ERGB;
|
|
||||||
if (pixelFormat == Bitmap::ESpectrumAlpha)
|
|
||||||
pixelFormat = Bitmap::ERGBA;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
fs::path filename = destFile;
|
fs::path filename = destFile;
|
||||||
std::string extension = boost::to_lower_copy(filename.extension().string());
|
std::string extension = boost::to_lower_copy(filename.extension().string());
|
||||||
if (extension != ".exr")
|
if (extension != ".exr")
|
||||||
|
@ -189,19 +230,22 @@ public:
|
||||||
header.setTileDescription(Imf::TileDescription(blockSize, blockSize, Imf::ONE_LEVEL));
|
header.setTileDescription(Imf::TileDescription(blockSize, blockSize, Imf::ONE_LEVEL));
|
||||||
header.insert("generated-by", Imf::StringAttribute("Mitsuba version " MTS_VERSION));
|
header.insert("generated-by", Imf::StringAttribute("Mitsuba version " MTS_VERSION));
|
||||||
|
|
||||||
if (pixelFormat == Bitmap::EXYZ || pixelFormat == Bitmap::EXYZA) {
|
if (m_pixelFormats.size() == 1) {
|
||||||
Imf::addChromaticities(header, Imf::Chromaticities(
|
/* Write a chromaticity tag when this is possible */
|
||||||
Imath::V2f(1.0f, 0.0f),
|
Bitmap::EPixelFormat pixelFormat = m_pixelFormats[0];
|
||||||
Imath::V2f(0.0f, 1.0f),
|
if (pixelFormat == Bitmap::EXYZ || pixelFormat == Bitmap::EXYZA) {
|
||||||
Imath::V2f(0.0f, 0.0f),
|
Imf::addChromaticities(header, Imf::Chromaticities(
|
||||||
Imath::V2f(1.0f/3.0f, 1.0f/3.0f)));
|
Imath::V2f(1.0f, 0.0f),
|
||||||
} else if (pixelFormat == Bitmap::ERGB || pixelFormat == Bitmap::ERGBA) {
|
Imath::V2f(0.0f, 1.0f),
|
||||||
Imf::addChromaticities(header, Imf::Chromaticities());
|
Imath::V2f(0.0f, 0.0f),
|
||||||
|
Imath::V2f(1.0f/3.0f, 1.0f/3.0f)));
|
||||||
|
} else if (pixelFormat == Bitmap::ERGB || pixelFormat == Bitmap::ERGBA) {
|
||||||
|
Imf::addChromaticities(header, Imf::Chromaticities());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Imf::PixelType compType;
|
Imf::PixelType compType;
|
||||||
size_t compStride;
|
size_t compStride;
|
||||||
int channelCount;
|
|
||||||
|
|
||||||
if (m_componentFormat == Bitmap::EFloat16) {
|
if (m_componentFormat == Bitmap::EFloat16) {
|
||||||
compType = Imf::HALF;
|
compType = Imf::HALF;
|
||||||
|
@ -219,62 +263,34 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
Imf::ChannelList &channels = header.channels();
|
Imf::ChannelList &channels = header.channels();
|
||||||
if (pixelFormat == Bitmap::ELuminance || pixelFormat == Bitmap::ELuminanceAlpha) {
|
for (size_t i=0; i<m_channelNames.size(); ++i)
|
||||||
channels.insert("Y", Imf::Channel(compType));
|
channels.insert(m_channelNames[i], Imf::Channel(compType));
|
||||||
channelCount = 1;
|
|
||||||
} else if (pixelFormat == Bitmap::ERGB || pixelFormat == Bitmap::ERGBA ||
|
|
||||||
pixelFormat == Bitmap::EXYZ || pixelFormat == Bitmap::EXYZA) {
|
|
||||||
channels.insert("R", Imf::Channel(compType));
|
|
||||||
channels.insert("G", Imf::Channel(compType));
|
|
||||||
channels.insert("B", Imf::Channel(compType));
|
|
||||||
channelCount = 3;
|
|
||||||
} else if (pixelFormat == Bitmap::ESpectrum || pixelFormat == Bitmap::ESpectrumAlpha) {
|
|
||||||
for (int i=0; i<SPECTRUM_SAMPLES; ++i) {
|
|
||||||
std::pair<Float, Float> coverage = Spectrum::getBinCoverage(i);
|
|
||||||
std::string name = formatString("%.2f-%.2fnm", coverage.first, coverage.second);
|
|
||||||
channels.insert(name.c_str(), Imf::Channel(compType));
|
|
||||||
}
|
|
||||||
channelCount = SPECTRUM_SAMPLES;
|
|
||||||
} else {
|
|
||||||
Log(EError, "Invalid pixel format!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_pixelFormat == Bitmap::ELuminanceAlpha || m_pixelFormat == Bitmap::ERGBA ||
|
|
||||||
m_pixelFormat == Bitmap::ESpectrumAlpha) {
|
|
||||||
channels.insert("A", Imf::Channel(compType));
|
|
||||||
channelCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_output = new Imf::TiledOutputFile(filename.string().c_str(), header);
|
m_output = new Imf::TiledOutputFile(filename.string().c_str(), header);
|
||||||
m_frameBuffer = new Imf::FrameBuffer();
|
m_frameBuffer = new Imf::FrameBuffer();
|
||||||
m_blockSize = (int) blockSize;
|
m_blockSize = (int) blockSize;
|
||||||
m_tile = new Bitmap(m_pixelFormat, m_componentFormat, Vector2i(m_blockSize, m_blockSize));
|
|
||||||
m_blocksH = (m_size.x + blockSize - 1) / blockSize;
|
m_blocksH = (m_size.x + blockSize - 1) / blockSize;
|
||||||
m_blocksV = (m_size.y + blockSize - 1) / blockSize;
|
m_blocksV = (m_size.y + blockSize - 1) / blockSize;
|
||||||
|
|
||||||
m_pixelStride = channelCount * compStride;
|
m_pixelStride = m_channelNames.size() * compStride;
|
||||||
m_rowStride = m_pixelStride * m_blockSize;
|
m_rowStride = m_pixelStride * m_blockSize;
|
||||||
char *ptr = (char *) m_tile->getUInt8Data();
|
|
||||||
|
|
||||||
if (pixelFormat == Bitmap::ELuminance || pixelFormat == Bitmap::ELuminanceAlpha) {
|
if (m_pixelFormats.size() == 1) {
|
||||||
m_frameBuffer->insert("Y", Imf::Slice(compType, ptr, m_pixelStride, m_rowStride)); ptr += compStride;
|
m_tile = new Bitmap(m_pixelFormats[0], m_componentFormat,
|
||||||
} else if (pixelFormat == Bitmap::ERGB || pixelFormat == Bitmap::ERGBA ||
|
Vector2i(m_blockSize, m_blockSize));
|
||||||
pixelFormat == Bitmap::EXYZ || pixelFormat == Bitmap::EXYZA) {
|
} else {
|
||||||
m_frameBuffer->insert("R", Imf::Slice(compType, ptr, m_pixelStride, m_rowStride)); ptr += compStride;
|
m_tile = new Bitmap(Bitmap::EMultiChannel, m_componentFormat,
|
||||||
m_frameBuffer->insert("G", Imf::Slice(compType, ptr, m_pixelStride, m_rowStride)); ptr += compStride;
|
Vector2i(m_blockSize, m_blockSize), m_channelNames.size());
|
||||||
m_frameBuffer->insert("B", Imf::Slice(compType, ptr, m_pixelStride, m_rowStride)); ptr += compStride;
|
m_tile->setChannelNames(m_channelNames);
|
||||||
} else if (pixelFormat == Bitmap::ESpectrum || pixelFormat == Bitmap::ESpectrumAlpha) {
|
|
||||||
for (int i=0; i<SPECTRUM_SAMPLES; ++i) {
|
|
||||||
std::pair<Float, Float> coverage = Spectrum::getBinCoverage(i);
|
|
||||||
std::string name = formatString("%f-%fnm", coverage.first, coverage.second);
|
|
||||||
m_frameBuffer->insert(name.c_str(), Imf::Slice(compType, ptr, m_pixelStride, m_rowStride)); ptr += compStride;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_pixelFormat == Bitmap::ERGBA || m_pixelFormat == Bitmap::EXYZA ||
|
char *ptr = (char *) m_tile->getUInt8Data();
|
||||||
m_pixelFormat == Bitmap::ELuminanceAlpha)
|
|
||||||
m_frameBuffer->insert("A", Imf::Slice(compType, ptr, m_pixelStride, m_rowStride));
|
for (size_t i=0; i<m_channelNames.size(); ++i) {
|
||||||
|
m_frameBuffer->insert(m_channelNames[i],
|
||||||
|
Imf::Slice(compType, ptr, m_pixelStride, m_rowStride));
|
||||||
|
ptr += compStride;
|
||||||
|
}
|
||||||
|
|
||||||
m_output->setFrameBuffer(*m_frameBuffer);
|
m_output->setFrameBuffer(*m_frameBuffer);
|
||||||
m_peakUsage = 0;
|
m_peakUsage = 0;
|
||||||
|
@ -388,6 +404,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
const Bitmap *source = mergedBlock->getBitmap();
|
const Bitmap *source = mergedBlock->getBitmap();
|
||||||
|
|
||||||
size_t sourceBpp = source->getBytesPerPixel();
|
size_t sourceBpp = source->getBytesPerPixel();
|
||||||
size_t targetBpp = m_tile->getBytesPerPixel();
|
size_t targetBpp = m_tile->getBytesPerPixel();
|
||||||
|
|
||||||
|
@ -400,11 +417,15 @@ public:
|
||||||
);
|
);
|
||||||
|
|
||||||
for (int i=0; i<m_blockSize; ++i) {
|
for (int i=0; i<m_blockSize; ++i) {
|
||||||
cvt->convert(source->getPixelFormat(), 1.0f, sourceData,
|
if (m_pixelFormats.size() == 1)
|
||||||
m_tile->getPixelFormat(), m_tile->getGamma(), targetData,
|
cvt->convert(source->getPixelFormat(), 1.0f, sourceData,
|
||||||
m_tile->getWidth());
|
m_tile->getPixelFormat(), m_tile->getGamma(), targetData,
|
||||||
|
m_tile->getWidth());
|
||||||
|
else
|
||||||
|
Bitmap::convertMultiSpectrumAlphaWeight(source, sourceData,
|
||||||
|
m_tile, targetData, m_pixelFormats, m_componentFormat, m_tile->getWidth());
|
||||||
|
|
||||||
sourceData += source->getWidth() * sourceBpp;
|
sourceData += source->getWidth() * sourceBpp;
|
||||||
targetData += m_tile->getWidth() * targetBpp;
|
targetData += m_tile->getWidth() * targetBpp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -470,11 +491,14 @@ public:
|
||||||
void clear() { /* Do nothing */ }
|
void clear() { /* Do nothing */ }
|
||||||
|
|
||||||
bool hasAlpha() const {
|
bool hasAlpha() const {
|
||||||
return
|
for (size_t i=0; i<m_pixelFormats.size(); ++i) {
|
||||||
m_pixelFormat == Bitmap::ELuminanceAlpha ||
|
if (m_pixelFormats[i] == Bitmap::ELuminanceAlpha ||
|
||||||
m_pixelFormat == Bitmap::ERGBA ||
|
m_pixelFormats[i] == Bitmap::ERGBA ||
|
||||||
m_pixelFormat == Bitmap::EXYZA ||
|
m_pixelFormats[i] == Bitmap::EXYZA ||
|
||||||
m_pixelFormat == Bitmap::ESpectrumAlpha;
|
m_pixelFormats[i] == Bitmap::ESpectrumAlpha)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool destinationExists(const fs::path &baseName) const {
|
bool destinationExists(const fs::path &baseName) const {
|
||||||
|
@ -488,7 +512,14 @@ public:
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "TiledHDRFilm[" << endl
|
oss << "TiledHDRFilm[" << endl
|
||||||
<< " size = " << m_size.toString() << "," << endl
|
<< " size = " << m_size.toString() << "," << endl
|
||||||
<< " pixelFormat = " << m_pixelFormat << "," << endl
|
<< " pixelFormat = ";
|
||||||
|
for (size_t i=0; i<m_pixelFormats.size(); ++i)
|
||||||
|
oss << m_pixelFormats[i] << ", ";
|
||||||
|
oss << endl
|
||||||
|
<< " channelNames = ";
|
||||||
|
for (size_t i=0; i<m_channelNames.size(); ++i)
|
||||||
|
oss << "\"" << m_channelNames[i] << "\"" << ", ";
|
||||||
|
oss << endl
|
||||||
<< " componentFormat = " << m_componentFormat << "," << endl
|
<< " componentFormat = " << m_componentFormat << "," << endl
|
||||||
<< " cropOffset = " << m_cropOffset.toString() << "," << endl
|
<< " cropOffset = " << m_cropOffset.toString() << "," << endl
|
||||||
<< " cropSize = " << m_cropSize.toString() << "," << endl
|
<< " cropSize = " << m_cropSize.toString() << "," << endl
|
||||||
|
@ -499,7 +530,8 @@ public:
|
||||||
|
|
||||||
MTS_DECLARE_CLASS()
|
MTS_DECLARE_CLASS()
|
||||||
protected:
|
protected:
|
||||||
Bitmap::EPixelFormat m_pixelFormat;
|
std::vector<Bitmap::EPixelFormat> m_pixelFormats;
|
||||||
|
std::vector<std::string> m_channelNames;
|
||||||
Bitmap::EComponentFormat m_componentFormat;
|
Bitmap::EComponentFormat m_componentFormat;
|
||||||
std::vector<ImageBlock *> m_freeBlocks;
|
std::vector<ImageBlock *> m_freeBlocks;
|
||||||
std::map<uint32_t, ImageBlock *> m_origBlocks, m_mergedBlocks;
|
std::map<uint32_t, ImageBlock *> m_origBlocks, m_mergedBlocks;
|
||||||
|
|
|
@ -23,7 +23,30 @@ MTS_NAMESPACE_BEGIN
|
||||||
|
|
||||||
/*! \plugin{direct}{Multi-channel integrator}
|
/*! \plugin{direct}{Multi-channel integrator}
|
||||||
* \order{16}
|
* \order{16}
|
||||||
|
* \parameters{
|
||||||
|
* \parameter{\Unnamed}{\BSDF}{Multiple sub-integrators whose output
|
||||||
|
* should be rendered into a combined multi-channel image}
|
||||||
|
* }
|
||||||
*
|
*
|
||||||
|
* The multi-channel integrator groups several sub-integrators together
|
||||||
|
* and invokes them at the same time for each pixel; the result is written
|
||||||
|
* to a general multi-channel image. The most common application of this plugin
|
||||||
|
* is to create additional image channels storing surface normals or the distance
|
||||||
|
* from the camera (via the \pluginref{field} plugin) or ambient occlusion
|
||||||
|
* (via the \pluginref{ao} plugin).
|
||||||
|
*
|
||||||
|
* This is a fairly advanced plugin that only plays well with a small
|
||||||
|
* part of Mitsuba---see the remarks in the red box for details.
|
||||||
|
*
|
||||||
|
* \remarks{
|
||||||
|
* \item Requires the \pluginref{hdrfilm} or \pluginref{tiledhdrfilm}.
|
||||||
|
* \item All nested integrators must
|
||||||
|
* conform to Mitsuba's basic \emph{SamplingIntegrator} interface.
|
||||||
|
* Currently, only a few of them satisfy this, including:
|
||||||
|
* \pluginref{field}, \pluginref{ao}, \pluginref{direct}, \pluginref{path},
|
||||||
|
* \pluginref{volpath}, \pluginref[volpathsimple]{volpath\_simple},
|
||||||
|
* and \pluginref{irrcache}.
|
||||||
|
* }
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class MultiChannelIntegrator : public SamplingIntegrator {
|
class MultiChannelIntegrator : public SamplingIntegrator {
|
||||||
|
|
|
@ -1361,7 +1361,7 @@ void Bitmap::convert(Bitmap *target, Float multiplier, Spectrum::EConversionInte
|
||||||
cvt->convert(m_pixelFormat, m_gamma, m_data,
|
cvt->convert(m_pixelFormat, m_gamma, m_data,
|
||||||
target->getPixelFormat(), target->getGamma(), target->getData(),
|
target->getPixelFormat(), target->getGamma(), target->getData(),
|
||||||
(size_t) m_size.x * (size_t) m_size.y, multiplier, intent,
|
(size_t) m_size.x * (size_t) m_size.y, multiplier, intent,
|
||||||
m_channelCount - (hasWeight() ? 1 : 0));
|
m_channelCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
ref<Bitmap> Bitmap::convert(EPixelFormat pixelFormat,
|
ref<Bitmap> Bitmap::convert(EPixelFormat pixelFormat,
|
||||||
|
@ -1392,70 +1392,96 @@ ref<Bitmap> Bitmap::convert(EPixelFormat pixelFormat,
|
||||||
cvt->convert(m_pixelFormat, m_gamma, m_data,
|
cvt->convert(m_pixelFormat, m_gamma, m_data,
|
||||||
pixelFormat, gamma, target->getData(),
|
pixelFormat, gamma, target->getData(),
|
||||||
(size_t) m_size.x * (size_t) m_size.y, multiplier, intent,
|
(size_t) m_size.x * (size_t) m_size.y, multiplier, intent,
|
||||||
m_channelCount - (hasWeight() ? 1 : 0));
|
m_channelCount);
|
||||||
|
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
ref<Bitmap> Bitmap::convertMultiSpectrumAlphaWeight(const std::vector<EPixelFormat> &pixelFormats,
|
ref<Bitmap> Bitmap::convertMultiSpectrumAlphaWeight(const std::vector<EPixelFormat> &pixelFormats,
|
||||||
EComponentFormat componentFormat, const std::vector<std::string> &channelNames) const {
|
EComponentFormat componentFormat, const std::vector<std::string> &channelNames) const {
|
||||||
if (m_componentFormat != EFloat && m_pixelFormat != EMultiSpectrumAlphaWeight)
|
ref<Bitmap> bitmap = new Bitmap(Bitmap::EMultiChannel, componentFormat, m_size, channelNames.size());
|
||||||
Log(EError, "convertMultiSpectrumAlphaWeight(): unsupported!");
|
|
||||||
ref<Bitmap> bitmap = new Bitmap(Bitmap::EMultiChannel, Bitmap::EFloat, m_size, channelNames.size());
|
|
||||||
bitmap->setChannelNames(channelNames);
|
bitmap->setChannelNames(channelNames);
|
||||||
|
convertMultiSpectrumAlphaWeight(this, getUInt8Data(), bitmap,
|
||||||
|
bitmap->getUInt8Data(), pixelFormats, componentFormat,
|
||||||
|
(size_t) m_size.x * (size_t) m_size.y);
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
for (int y = 0; y<m_size.y; ++y) {
|
void Bitmap::convertMultiSpectrumAlphaWeight(const Bitmap *source,
|
||||||
for (int x = 0; x<m_size.x; ++x) {
|
const uint8_t *sourcePtr, const Bitmap *target, uint8_t *targetPtr,
|
||||||
const Float *srcData = getFloatData() + getChannelCount() * (x+y*m_size.x);
|
const std::vector<EPixelFormat> &pixelFormats,
|
||||||
Float *dstData = bitmap->getFloatData() + bitmap->getChannelCount() * (x+y*m_size.x);
|
EComponentFormat componentFormat, size_t count) {
|
||||||
Float weight = srcData[getChannelCount()-1],
|
if (source->getComponentFormat() != EFloat && source->getPixelFormat() != EMultiSpectrumAlphaWeight)
|
||||||
invWeight = weight == 0 ? 0 : (Float) 1 / weight;
|
Log(EError, "convertMultiSpectrumAlphaWeight(): unsupported!");
|
||||||
Float alpha = srcData[getChannelCount()-2] * invWeight;
|
|
||||||
|
|
||||||
for (size_t i=0; i<pixelFormats.size(); ++i) {
|
Float *temp = new Float[count * target->getChannelCount()], *dst = temp;
|
||||||
Spectrum value = ((Spectrum *) srcData)[i] * invWeight;
|
|
||||||
Float r, g, b;
|
for (size_t k = 0; k<count; ++k) {
|
||||||
switch (pixelFormats[i]) {
|
const Float *srcData = (const Float *) sourcePtr + k * source->getChannelCount();
|
||||||
case Bitmap::ELuminance:
|
Float weight = srcData[source->getChannelCount()-1],
|
||||||
*dstData++ = value.getLuminance();
|
invWeight = weight == 0 ? 0 : (Float) 1 / weight;
|
||||||
break;
|
Float alpha = srcData[source->getChannelCount()-2] * invWeight;
|
||||||
case Bitmap::ELuminanceAlpha:
|
|
||||||
*dstData++ = value.getLuminance();
|
for (size_t i=0; i<pixelFormats.size(); ++i) {
|
||||||
*dstData++ = alpha;
|
Spectrum value = ((Spectrum *) srcData)[i] * invWeight;
|
||||||
break;
|
Float tmp0, tmp1, tmp2;
|
||||||
case Bitmap::ERGB:
|
switch (pixelFormats[i]) {
|
||||||
value.toLinearRGB(r, g, b);
|
case Bitmap::ELuminance:
|
||||||
*dstData++ = r;
|
*dst++ = value.getLuminance();
|
||||||
*dstData++ = g;
|
break;
|
||||||
*dstData++ = b;
|
case Bitmap::ELuminanceAlpha:
|
||||||
break;
|
*dst++ = value.getLuminance();
|
||||||
case Bitmap::ERGBA:
|
*dst++ = alpha;
|
||||||
value.toLinearRGB(r, g, b);
|
break;
|
||||||
*dstData++ = r;
|
case Bitmap::EXYZ:
|
||||||
*dstData++ = g;
|
value.toXYZ(tmp0, tmp1, tmp2);
|
||||||
*dstData++ = b;
|
*dst++ = tmp0;
|
||||||
*dstData++ = alpha;
|
*dst++ = tmp1;
|
||||||
break;
|
*dst++ = tmp2;
|
||||||
case Bitmap::ESpectrum:
|
break;
|
||||||
for (int j=0; j<SPECTRUM_SAMPLES; ++j)
|
case Bitmap::EXYZA:
|
||||||
*dstData++ = value[j];
|
value.toXYZ(tmp0, tmp1, tmp2);
|
||||||
break;
|
*dst++ = tmp0;
|
||||||
case Bitmap::ESpectrumAlpha:
|
*dst++ = tmp1;
|
||||||
for (int j=0; j<SPECTRUM_SAMPLES; ++j)
|
*dst++ = tmp2;
|
||||||
*dstData++ = value[j];
|
*dst++ = alpha;
|
||||||
*dstData++ = alpha;
|
break;
|
||||||
break;
|
case Bitmap::ERGB:
|
||||||
default:
|
value.toLinearRGB(tmp0, tmp1, tmp2);
|
||||||
Log(EError, "Unknown pixel format!");
|
*dst++ = tmp0;
|
||||||
}
|
*dst++ = tmp1;
|
||||||
|
*dst++ = tmp2;
|
||||||
|
break;
|
||||||
|
case Bitmap::ERGBA:
|
||||||
|
value.toLinearRGB(tmp0, tmp1, tmp2);
|
||||||
|
*dst++ = tmp0;
|
||||||
|
*dst++ = tmp1;
|
||||||
|
*dst++ = tmp2;
|
||||||
|
*dst++ = alpha;
|
||||||
|
break;
|
||||||
|
case Bitmap::ESpectrum:
|
||||||
|
for (int j=0; j<SPECTRUM_SAMPLES; ++j)
|
||||||
|
*dst++ = value[j];
|
||||||
|
break;
|
||||||
|
case Bitmap::ESpectrumAlpha:
|
||||||
|
for (int j=0; j<SPECTRUM_SAMPLES; ++j)
|
||||||
|
*dst++ = value[j];
|
||||||
|
*dst++ = alpha;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Log(EError, "Unknown pixel format!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (componentFormat != Bitmap::EFloat)
|
const FormatConverter *cvt = FormatConverter::getInstance(
|
||||||
bitmap = bitmap->convert(Bitmap::EMultiChannel, componentFormat);
|
std::make_pair(EFloat, target->getComponentFormat())
|
||||||
|
);
|
||||||
|
|
||||||
return bitmap;
|
cvt->convert(Bitmap::EMultiChannel, 1.0f, temp, Bitmap::EMultiChannel, 1.0f, targetPtr,
|
||||||
|
count, 1.0f, Spectrum::EReflectance, target->getChannelCount());
|
||||||
|
|
||||||
|
delete[] temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bitmap::convert(void *target, EPixelFormat pixelFormat,
|
void Bitmap::convert(void *target, EPixelFormat pixelFormat,
|
||||||
|
@ -1481,7 +1507,7 @@ void Bitmap::convert(void *target, EPixelFormat pixelFormat,
|
||||||
cvt->convert(m_pixelFormat, m_gamma, m_data,
|
cvt->convert(m_pixelFormat, m_gamma, m_data,
|
||||||
pixelFormat, gamma, target,
|
pixelFormat, gamma, target,
|
||||||
(size_t) m_size.x * (size_t) m_size.y, multiplier, intent,
|
(size_t) m_size.x * (size_t) m_size.y, multiplier, intent,
|
||||||
m_channelCount - (hasWeight() ? 1 : 0));
|
m_channelCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> void tonemapReinhard(T *data, size_t pixels, Bitmap::EPixelFormat fmt,
|
template <typename T> void tonemapReinhard(T *data, size_t pixels, Bitmap::EPixelFormat fmt,
|
||||||
|
|
Loading…
Reference in New Issue