debugging..
parent
ee5b29878f
commit
8d84d0b1a0
|
@ -678,12 +678,17 @@ public:
|
|||
* specified component format. Names for each of the resulting channels should
|
||||
* be provided via the \c channelNames parameters.
|
||||
*
|
||||
* This function is currently only used by the \c hdrfilm plugin but located here
|
||||
* as it is tied to the internals of this class.
|
||||
* This feature is currently used by the \c hdrfilm and \c tiledhdrfilm plugins.
|
||||
*/
|
||||
ref<Bitmap> convertMultiSpectrumAlphaWeight(const std::vector<EPixelFormat> &pixelFormats,
|
||||
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
|
||||
*
|
||||
|
|
|
@ -215,7 +215,7 @@ public:
|
|||
std::vector<std::string> pixelFormats = tokenize(boost::to_lower_copy(
|
||||
props.getString("pixelFormat", "rgb")), " ,");
|
||||
std::vector<std::string> channelNames = tokenize(
|
||||
props.getString("channelNames", "rgb"), ", ");
|
||||
props.getString("channelNames", ""), ", ");
|
||||
std::string componentFormat = boost::to_lower_copy(
|
||||
props.getString("componentFormat", "float16"));
|
||||
|
||||
|
@ -238,47 +238,50 @@ public:
|
|||
|
||||
for (size_t i=0; i<pixelFormats.size(); ++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") {
|
||||
m_pixelFormats.push_back(Bitmap::ELuminance);
|
||||
m_channelNames.push_back(name + ".Y");
|
||||
m_channelNames.push_back(name + "Y");
|
||||
} else if (pixelFormat == "luminancealpha") {
|
||||
m_pixelFormats.push_back(Bitmap::ELuminanceAlpha);
|
||||
m_channelNames.push_back(name + ".Y");
|
||||
m_channelNames.push_back(name + ".A");
|
||||
m_channelNames.push_back(name + "Y");
|
||||
m_channelNames.push_back(name + "A");
|
||||
} else if (pixelFormat == "rgb") {
|
||||
m_pixelFormats.push_back(Bitmap::ERGB);
|
||||
m_channelNames.push_back(name + ".R");
|
||||
m_channelNames.push_back(name + ".G");
|
||||
m_channelNames.push_back(name + ".B");
|
||||
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");
|
||||
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);
|
||||
if (m_pixelFormats.size() > 1)
|
||||
Log(EError, "The XYZ pixel format is not supported for general multi-channel images!");
|
||||
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);
|
||||
if (m_pixelFormats.size() > 1)
|
||||
Log(EError, "The XYZA pixel format is not supported for general multi-channel images!");
|
||||
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));
|
||||
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 + formatString("%.2f-%.2fnm", coverage.first, coverage.second));
|
||||
}
|
||||
m_channelNames.push_back(name + ".A");
|
||||
m_channelNames.push_back(name + "A");
|
||||
} else {
|
||||
Log(EError, "The \"pixelFormat\" parameter must either be equal to "
|
||||
"\"luminance\", \"luminanceAlpha\", \"rgb\", \"rgba\", \"xyz\", \"xyza\", "
|
||||
|
@ -529,13 +532,14 @@ public:
|
|||
}
|
||||
|
||||
bool hasAlpha() const {
|
||||
Assert(m_pixelFormats.size() > 0);
|
||||
return
|
||||
m_pixelFormats[0] == Bitmap::ELuminanceAlpha ||
|
||||
m_pixelFormats[0] == Bitmap::ERGBA ||
|
||||
m_pixelFormats[0] == Bitmap::EXYZA ||
|
||||
m_pixelFormats[0] == Bitmap::ESpectrumAlpha ||
|
||||
m_pixelFormats.size() > 1;
|
||||
for (size_t i=0; i<m_pixelFormats.size(); ++i) {
|
||||
if (m_pixelFormats[i] == Bitmap::ELuminanceAlpha ||
|
||||
m_pixelFormats[i] == Bitmap::ERGBA ||
|
||||
m_pixelFormats[i] == Bitmap::EXYZA ||
|
||||
m_pixelFormats[i] == Bitmap::ESpectrumAlpha)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool destinationExists(const fs::path &baseName) const {
|
||||
|
|
|
@ -101,37 +101,78 @@ MTS_NAMESPACE_BEGIN
|
|||
class TiledHDRFilm : public Film {
|
||||
public:
|
||||
TiledHDRFilm(const Properties &props) : Film(props), m_output(NULL), m_frameBuffer(NULL) {
|
||||
std::string pixelFormat = boost::to_lower_copy(
|
||||
props.getString("pixelFormat", "rgb"));
|
||||
std::vector<std::string> pixelFormats = tokenize(boost::to_lower_copy(
|
||||
props.getString("pixelFormat", "rgb")), " ,");
|
||||
std::vector<std::string> channelNames = tokenize(
|
||||
props.getString("channelNames", ""), ", ");
|
||||
std::string componentFormat = boost::to_lower_copy(
|
||||
props.getString("componentFormat", "float16"));
|
||||
|
||||
if (pixelFormat == "luminance") {
|
||||
m_pixelFormat = Bitmap::ELuminance;
|
||||
} else if (pixelFormat == "luminancealpha") {
|
||||
m_pixelFormat = Bitmap::ELuminanceAlpha;
|
||||
} else if (pixelFormat == "rgb") {
|
||||
m_pixelFormat = Bitmap::ERGB;
|
||||
} else if (pixelFormat == "rgba") {
|
||||
m_pixelFormat = Bitmap::ERGBA;
|
||||
} else if (pixelFormat == "xyz") {
|
||||
m_pixelFormat = Bitmap::EXYZ;
|
||||
} else if (pixelFormat == "xyza") {
|
||||
m_pixelFormat = Bitmap::EXYZA;
|
||||
} else if (pixelFormat == "spectrum") {
|
||||
m_pixelFormat = Bitmap::ESpectrum;
|
||||
} else if (pixelFormat == "spectrumalpha") {
|
||||
m_pixelFormat = Bitmap::ESpectrumAlpha;
|
||||
} else {
|
||||
Log(EError, "The \"pixelFormat\" parameter must either be equal to "
|
||||
"\"luminance\", \"luminanceAlpha\", \"rgb\", \"rgba\", \"xyz\", \"xyza\", "
|
||||
"\"spectrum\", or \"spectrumAlpha\"!");
|
||||
if (pixelFormats.empty())
|
||||
Log(EError, "At least one pixel format must be specified!");
|
||||
|
||||
if (m_pixelFormats.size() != 1 && m_channelNames.size() != m_pixelFormats.size())
|
||||
Log(EError, "Number of channel names must match the number of specified pixel formats!");
|
||||
|
||||
for (size_t i=0; i<pixelFormats.size(); ++i) {
|
||||
std::string pixelFormat = pixelFormats[i];
|
||||
std::string name = i < channelNames.size() ? (channelNames[i] + std::string(".")) : "";
|
||||
|
||||
if (pixelFormat == "luminance") {
|
||||
m_pixelFormats.push_back(Bitmap::ELuminance);
|
||||
m_channelNames.push_back(name + "Y");
|
||||
} else if (pixelFormat == "luminancealpha") {
|
||||
m_pixelFormats.push_back(Bitmap::ELuminanceAlpha);
|
||||
m_channelNames.push_back(name + "Y");
|
||||
m_channelNames.push_back(name + "A");
|
||||
} else if (pixelFormat == "rgb") {
|
||||
m_pixelFormats.push_back(Bitmap::ERGB);
|
||||
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))
|
||||
Log(EError, "You requested to render a spectral image, but Mitsuba is currently "
|
||||
"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.");
|
||||
for (size_t i=0; i<m_pixelFormats.size(); ++i) {
|
||||
if (SPECTRUM_SAMPLES == 3 && (m_pixelFormats[i] == Bitmap::ESpectrum || m_pixelFormats[i] == Bitmap::ESpectrumAlpha))
|
||||
Log(EError, "You requested to render a spectral image, but Mitsuba is currently "
|
||||
"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") {
|
||||
m_componentFormat = Bitmap::EFloat16;
|
||||
|
@ -151,7 +192,12 @@ public:
|
|||
|
||||
TiledHDRFilm(Stream *stream, InstanceManager *manager)
|
||||
: 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();
|
||||
}
|
||||
|
||||
|
@ -161,7 +207,11 @@ public:
|
|||
|
||||
void serialize(Stream *stream, InstanceManager *manager) const {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -169,15 +219,6 @@ public:
|
|||
if (m_output)
|
||||
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;
|
||||
std::string extension = boost::to_lower_copy(filename.extension().string());
|
||||
if (extension != ".exr")
|
||||
|
@ -189,19 +230,22 @@ public:
|
|||
header.setTileDescription(Imf::TileDescription(blockSize, blockSize, Imf::ONE_LEVEL));
|
||||
header.insert("generated-by", Imf::StringAttribute("Mitsuba version " MTS_VERSION));
|
||||
|
||||
if (pixelFormat == Bitmap::EXYZ || pixelFormat == Bitmap::EXYZA) {
|
||||
Imf::addChromaticities(header, Imf::Chromaticities(
|
||||
Imath::V2f(1.0f, 0.0f),
|
||||
Imath::V2f(0.0f, 1.0f),
|
||||
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());
|
||||
if (m_pixelFormats.size() == 1) {
|
||||
/* Write a chromaticity tag when this is possible */
|
||||
Bitmap::EPixelFormat pixelFormat = m_pixelFormats[0];
|
||||
if (pixelFormat == Bitmap::EXYZ || pixelFormat == Bitmap::EXYZA) {
|
||||
Imf::addChromaticities(header, Imf::Chromaticities(
|
||||
Imath::V2f(1.0f, 0.0f),
|
||||
Imath::V2f(0.0f, 1.0f),
|
||||
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;
|
||||
size_t compStride;
|
||||
int channelCount;
|
||||
|
||||
if (m_componentFormat == Bitmap::EFloat16) {
|
||||
compType = Imf::HALF;
|
||||
|
@ -219,62 +263,34 @@ public:
|
|||
}
|
||||
|
||||
Imf::ChannelList &channels = header.channels();
|
||||
if (pixelFormat == Bitmap::ELuminance || pixelFormat == Bitmap::ELuminanceAlpha) {
|
||||
channels.insert("Y", 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++;
|
||||
}
|
||||
for (size_t i=0; i<m_channelNames.size(); ++i)
|
||||
channels.insert(m_channelNames[i], Imf::Channel(compType));
|
||||
|
||||
m_output = new Imf::TiledOutputFile(filename.string().c_str(), header);
|
||||
m_frameBuffer = new Imf::FrameBuffer();
|
||||
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_blocksV = (m_size.y + blockSize - 1) / blockSize;
|
||||
|
||||
m_pixelStride = channelCount * compStride;
|
||||
m_pixelStride = m_channelNames.size() * compStride;
|
||||
m_rowStride = m_pixelStride * m_blockSize;
|
||||
char *ptr = (char *) m_tile->getUInt8Data();
|
||||
|
||||
if (pixelFormat == Bitmap::ELuminance || pixelFormat == Bitmap::ELuminanceAlpha) {
|
||||
m_frameBuffer->insert("Y", Imf::Slice(compType, ptr, m_pixelStride, m_rowStride)); ptr += compStride;
|
||||
} else if (pixelFormat == Bitmap::ERGB || pixelFormat == Bitmap::ERGBA ||
|
||||
pixelFormat == Bitmap::EXYZ || pixelFormat == Bitmap::EXYZA) {
|
||||
m_frameBuffer->insert("R", Imf::Slice(compType, ptr, m_pixelStride, m_rowStride)); ptr += compStride;
|
||||
m_frameBuffer->insert("G", Imf::Slice(compType, ptr, m_pixelStride, m_rowStride)); ptr += compStride;
|
||||
m_frameBuffer->insert("B", Imf::Slice(compType, ptr, m_pixelStride, m_rowStride)); ptr += compStride;
|
||||
} 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_pixelFormats.size() == 1) {
|
||||
m_tile = new Bitmap(m_pixelFormats[0], m_componentFormat,
|
||||
Vector2i(m_blockSize, m_blockSize));
|
||||
} else {
|
||||
m_tile = new Bitmap(Bitmap::EMultiChannel, m_componentFormat,
|
||||
Vector2i(m_blockSize, m_blockSize), m_channelNames.size());
|
||||
m_tile->setChannelNames(m_channelNames);
|
||||
}
|
||||
|
||||
if (m_pixelFormat == Bitmap::ERGBA || m_pixelFormat == Bitmap::EXYZA ||
|
||||
m_pixelFormat == Bitmap::ELuminanceAlpha)
|
||||
m_frameBuffer->insert("A", Imf::Slice(compType, ptr, m_pixelStride, m_rowStride));
|
||||
char *ptr = (char *) m_tile->getUInt8Data();
|
||||
|
||||
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_peakUsage = 0;
|
||||
|
@ -388,6 +404,7 @@ public:
|
|||
}
|
||||
|
||||
const Bitmap *source = mergedBlock->getBitmap();
|
||||
|
||||
size_t sourceBpp = source->getBytesPerPixel();
|
||||
size_t targetBpp = m_tile->getBytesPerPixel();
|
||||
|
||||
|
@ -400,11 +417,15 @@ public:
|
|||
);
|
||||
|
||||
for (int i=0; i<m_blockSize; ++i) {
|
||||
cvt->convert(source->getPixelFormat(), 1.0f, sourceData,
|
||||
m_tile->getPixelFormat(), m_tile->getGamma(), targetData,
|
||||
m_tile->getWidth());
|
||||
if (m_pixelFormats.size() == 1)
|
||||
cvt->convert(source->getPixelFormat(), 1.0f, sourceData,
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -470,11 +491,14 @@ public:
|
|||
void clear() { /* Do nothing */ }
|
||||
|
||||
bool hasAlpha() const {
|
||||
return
|
||||
m_pixelFormat == Bitmap::ELuminanceAlpha ||
|
||||
m_pixelFormat == Bitmap::ERGBA ||
|
||||
m_pixelFormat == Bitmap::EXYZA ||
|
||||
m_pixelFormat == Bitmap::ESpectrumAlpha;
|
||||
for (size_t i=0; i<m_pixelFormats.size(); ++i) {
|
||||
if (m_pixelFormats[i] == Bitmap::ELuminanceAlpha ||
|
||||
m_pixelFormats[i] == Bitmap::ERGBA ||
|
||||
m_pixelFormats[i] == Bitmap::EXYZA ||
|
||||
m_pixelFormats[i] == Bitmap::ESpectrumAlpha)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool destinationExists(const fs::path &baseName) const {
|
||||
|
@ -488,7 +512,14 @@ public:
|
|||
std::ostringstream oss;
|
||||
oss << "TiledHDRFilm[" << 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
|
||||
<< " cropOffset = " << m_cropOffset.toString() << "," << endl
|
||||
<< " cropSize = " << m_cropSize.toString() << "," << endl
|
||||
|
@ -499,7 +530,8 @@ public:
|
|||
|
||||
MTS_DECLARE_CLASS()
|
||||
protected:
|
||||
Bitmap::EPixelFormat m_pixelFormat;
|
||||
std::vector<Bitmap::EPixelFormat> m_pixelFormats;
|
||||
std::vector<std::string> m_channelNames;
|
||||
Bitmap::EComponentFormat m_componentFormat;
|
||||
std::vector<ImageBlock *> m_freeBlocks;
|
||||
std::map<uint32_t, ImageBlock *> m_origBlocks, m_mergedBlocks;
|
||||
|
|
|
@ -23,7 +23,30 @@ MTS_NAMESPACE_BEGIN
|
|||
|
||||
/*! \plugin{direct}{Multi-channel integrator}
|
||||
* \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 {
|
||||
|
|
|
@ -1361,7 +1361,7 @@ void Bitmap::convert(Bitmap *target, Float multiplier, Spectrum::EConversionInte
|
|||
cvt->convert(m_pixelFormat, m_gamma, m_data,
|
||||
target->getPixelFormat(), target->getGamma(), target->getData(),
|
||||
(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,
|
||||
|
@ -1392,70 +1392,96 @@ ref<Bitmap> Bitmap::convert(EPixelFormat pixelFormat,
|
|||
cvt->convert(m_pixelFormat, m_gamma, m_data,
|
||||
pixelFormat, gamma, target->getData(),
|
||||
(size_t) m_size.x * (size_t) m_size.y, multiplier, intent,
|
||||
m_channelCount - (hasWeight() ? 1 : 0));
|
||||
m_channelCount);
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
ref<Bitmap> Bitmap::convertMultiSpectrumAlphaWeight(const std::vector<EPixelFormat> &pixelFormats,
|
||||
EComponentFormat componentFormat, const std::vector<std::string> &channelNames) const {
|
||||
if (m_componentFormat != EFloat && m_pixelFormat != EMultiSpectrumAlphaWeight)
|
||||
Log(EError, "convertMultiSpectrumAlphaWeight(): unsupported!");
|
||||
ref<Bitmap> bitmap = new Bitmap(Bitmap::EMultiChannel, Bitmap::EFloat, m_size, channelNames.size());
|
||||
ref<Bitmap> bitmap = new Bitmap(Bitmap::EMultiChannel, componentFormat, m_size, channelNames.size());
|
||||
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) {
|
||||
for (int x = 0; x<m_size.x; ++x) {
|
||||
const Float *srcData = getFloatData() + getChannelCount() * (x+y*m_size.x);
|
||||
Float *dstData = bitmap->getFloatData() + bitmap->getChannelCount() * (x+y*m_size.x);
|
||||
Float weight = srcData[getChannelCount()-1],
|
||||
invWeight = weight == 0 ? 0 : (Float) 1 / weight;
|
||||
Float alpha = srcData[getChannelCount()-2] * invWeight;
|
||||
void Bitmap::convertMultiSpectrumAlphaWeight(const Bitmap *source,
|
||||
const uint8_t *sourcePtr, const Bitmap *target, uint8_t *targetPtr,
|
||||
const std::vector<EPixelFormat> &pixelFormats,
|
||||
EComponentFormat componentFormat, size_t count) {
|
||||
if (source->getComponentFormat() != EFloat && source->getPixelFormat() != EMultiSpectrumAlphaWeight)
|
||||
Log(EError, "convertMultiSpectrumAlphaWeight(): unsupported!");
|
||||
|
||||
for (size_t i=0; i<pixelFormats.size(); ++i) {
|
||||
Spectrum value = ((Spectrum *) srcData)[i] * invWeight;
|
||||
Float r, g, b;
|
||||
switch (pixelFormats[i]) {
|
||||
case Bitmap::ELuminance:
|
||||
*dstData++ = value.getLuminance();
|
||||
break;
|
||||
case Bitmap::ELuminanceAlpha:
|
||||
*dstData++ = value.getLuminance();
|
||||
*dstData++ = alpha;
|
||||
break;
|
||||
case Bitmap::ERGB:
|
||||
value.toLinearRGB(r, g, b);
|
||||
*dstData++ = r;
|
||||
*dstData++ = g;
|
||||
*dstData++ = b;
|
||||
break;
|
||||
case Bitmap::ERGBA:
|
||||
value.toLinearRGB(r, g, b);
|
||||
*dstData++ = r;
|
||||
*dstData++ = g;
|
||||
*dstData++ = b;
|
||||
*dstData++ = alpha;
|
||||
break;
|
||||
case Bitmap::ESpectrum:
|
||||
for (int j=0; j<SPECTRUM_SAMPLES; ++j)
|
||||
*dstData++ = value[j];
|
||||
break;
|
||||
case Bitmap::ESpectrumAlpha:
|
||||
for (int j=0; j<SPECTRUM_SAMPLES; ++j)
|
||||
*dstData++ = value[j];
|
||||
*dstData++ = alpha;
|
||||
break;
|
||||
default:
|
||||
Log(EError, "Unknown pixel format!");
|
||||
}
|
||||
Float *temp = new Float[count * target->getChannelCount()], *dst = temp;
|
||||
|
||||
for (size_t k = 0; k<count; ++k) {
|
||||
const Float *srcData = (const Float *) sourcePtr + k * source->getChannelCount();
|
||||
Float weight = srcData[source->getChannelCount()-1],
|
||||
invWeight = weight == 0 ? 0 : (Float) 1 / weight;
|
||||
Float alpha = srcData[source->getChannelCount()-2] * invWeight;
|
||||
|
||||
for (size_t i=0; i<pixelFormats.size(); ++i) {
|
||||
Spectrum value = ((Spectrum *) srcData)[i] * invWeight;
|
||||
Float tmp0, tmp1, tmp2;
|
||||
switch (pixelFormats[i]) {
|
||||
case Bitmap::ELuminance:
|
||||
*dst++ = value.getLuminance();
|
||||
break;
|
||||
case Bitmap::ELuminanceAlpha:
|
||||
*dst++ = value.getLuminance();
|
||||
*dst++ = alpha;
|
||||
break;
|
||||
case Bitmap::EXYZ:
|
||||
value.toXYZ(tmp0, tmp1, tmp2);
|
||||
*dst++ = tmp0;
|
||||
*dst++ = tmp1;
|
||||
*dst++ = tmp2;
|
||||
break;
|
||||
case Bitmap::EXYZA:
|
||||
value.toXYZ(tmp0, tmp1, tmp2);
|
||||
*dst++ = tmp0;
|
||||
*dst++ = tmp1;
|
||||
*dst++ = tmp2;
|
||||
*dst++ = alpha;
|
||||
break;
|
||||
case Bitmap::ERGB:
|
||||
value.toLinearRGB(tmp0, tmp1, tmp2);
|
||||
*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)
|
||||
bitmap = bitmap->convert(Bitmap::EMultiChannel, componentFormat);
|
||||
const FormatConverter *cvt = FormatConverter::getInstance(
|
||||
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,
|
||||
|
@ -1481,7 +1507,7 @@ void Bitmap::convert(void *target, EPixelFormat pixelFormat,
|
|||
cvt->convert(m_pixelFormat, m_gamma, m_data,
|
||||
pixelFormat, gamma, target,
|
||||
(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,
|
||||
|
|
Loading…
Reference in New Issue