diff --git a/src/films/CMakeLists.txt b/src/films/CMakeLists.txt index c9633ce8..22ff2e8e 100644 --- a/src/films/CMakeLists.txt +++ b/src/films/CMakeLists.txt @@ -8,8 +8,8 @@ macro(add_film) endmacro() add_film(mfilm mfilm.cpp) -add_film(ldrfilm ldrfilm.cpp banner.h MTS_HW) -add_film(hdrfilm hdrfilm.cpp banner.h MTS_HW) +add_film(ldrfilm ldrfilm.cpp annotations.h banner.h MTS_HW) +add_film(hdrfilm hdrfilm.cpp annotations.h banner.h MTS_HW) if (OPENEXR_FOUND) include_directories(${ILMBASE_INCLUDE_DIRS} ${OPENEXR_INCLUDE_DIRS}) diff --git a/src/films/annotations.h b/src/films/annotations.h new file mode 100644 index 00000000..6d041e03 --- /dev/null +++ b/src/films/annotations.h @@ -0,0 +1,137 @@ +/* + This file is part of Mitsuba, a physically based rendering system. + + Copyright (c) 2007-2012 by Wenzel Jakob and others. + + Mitsuba is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License Version 3 + as published by the Free Software Foundation. + + Mitsuba is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once +#if !defined(__ANNOTATIONS_H) +#define __ANNOTATIONS_H + +#include +#include + +MTS_NAMESPACE_BEGIN + +/** + * This function implements a parser for the 'label[]' and 'metadata[]' + * annotations supported by the ldrfilm and hdrfilm plugins + */ +void annotate(const Scene *scene, const Properties &properties, + Bitmap *bitmap, Float renderTime, Float gamma) { + /* Attach the custom annotations */ + Properties &metadata = bitmap->getMetadata(); + std::vector keys = properties.getPropertyNames(); + ref font; + + for (size_t i=0; i args = tokenize(key.substr(6, key.length()-7), " ,"); + if (args.size() != 2) + SLog(EError, "Label command '%s' has an invalid number of arguments!", key.c_str()); + char *end_ptr = NULL; + offset.x = strtol(args[0].c_str(), &end_ptr, 10); + if (*end_ptr != '\0') + SLog(EError, "Label command '%s' has an invalid position argument!", key.c_str()); + offset.y = strtol(args[1].c_str(), &end_ptr, 10); + if (*end_ptr != '\0') + SLog(EError, "Label command '%s' has an invalid position argument!", key.c_str()); + labelAnnotation = true; + + if (font == NULL) { + font = new Font(Font::EBitstreamVeraMono14); + font->convert(bitmap->getPixelFormat(), bitmap->getComponentFormat(), gamma); + } + } else { + continue; + } + + Properties::EPropertyType type = properties.getType(keys[i]); + if (type == Properties::EString) { + std::string value = properties.getString(keys[i]); + + while (true) { + char *strt; + if (!(strt = strchr((char *) value.c_str(), '$'))) + break; + + if (strncasecmp(strt, "$rendertime", 11) == 0) { + value.replace(strt-value.c_str(), 11, timeString(renderTime)); + } else if (strncasecmp(strt, "$memusage", 11) == 0) { + value.replace(strt-value.c_str(), 11, memString(getPrivateMemoryUsage())); + } else { + char *par1, *par2; + if (!(par1 = strchr(strt, '['))) + break; + if (!(par2 = strchr(par1, ']'))) + break; + + std::string propSource = value.substr(strt-value.c_str()+1, par1-strt-1); + std::string propKey = value.substr(par1-value.c_str()+1, par2-par1-1); + propSource.erase(std::remove_if(propSource.begin(), propSource.end(), ::isspace), propSource.end()); + propKey.erase(std::remove_if(propKey.begin(), propKey.end(), ::isspace), propKey.end()); + + if (!boost::starts_with(propKey, "'") || !boost::ends_with(propKey, "'")) + SLog(EError, "Encountered invalid key '%s'", propKey.c_str()); + + propKey = propKey.substr(1, propKey.length()-2); + + const ConfigurableObject *source = NULL; + if (propSource == "film") + source = scene->getFilm(); + else if (propSource == "sampler") + source = scene->getSampler(); + else if (propSource == "sensor") + source = scene->getSensor(); + else if (propSource == "integrator") + source = scene->getIntegrator(); + else + SLog(EError, "Unknown data source '%s' (must be film/sampler/sensor/integrator)", propSource.c_str()); + + std::string replacement; + if (propKey == "type") + replacement = source->getProperties().getPluginName(); + else + replacement = source->getProperties().getAsString(propKey); + + value.replace(strt-value.c_str(), par2-strt+1, replacement); + } + } + if (labelAnnotation) { + Vector2i size = font->getSize(value); + bitmap->fillRect(offset-Vector2i(4, 4), size + Vector2i(8, 8), Spectrum(0.0f)); + font->drawText(bitmap, offset, value); + } else { + metadata.setString(key, value); + } + } else { + if (labelAnnotation) + SLog(EError, "Only string-valued label annotations are supported!"); + metadata.copyAttribute(properties, keys[i], key); + } + } +} + +MTS_NAMESPACE_END + +#endif /* __ANNOTATIONS_H */ diff --git a/src/films/hdrfilm.cpp b/src/films/hdrfilm.cpp index d71508c6..8bb01a3c 100644 --- a/src/films/hdrfilm.cpp +++ b/src/films/hdrfilm.cpp @@ -20,10 +20,9 @@ #include #include #include -#include #include -#include #include "banner.h" +#include "annotations.h" MTS_NAMESPACE_BEGIN @@ -369,107 +368,7 @@ public: Log(EInfo, "Writing image to \"%s\" ..", filename.string().c_str()); ref stream = new FileStream(filename, FileStream::ETruncWrite); - /* Attach the custom annotations */ - Properties &metadata = bitmap->getMetadata(); - std::vector keys = m_properties.getPropertyNames(); - ref font; - Float gamma = 1.0f; /// XXX - - for (size_t i=0; i args = tokenize(key.substr(6, key.length()-7), " ,"); - if (args.size() != 2) - Log(EError, "Label command '%s' has an invalid number of arguments!", key.c_str()); - char *end_ptr = NULL; - offset.x = strtol(args[0].c_str(), &end_ptr, 10); - if (*end_ptr != '\0') - Log(EError, "Label command '%s' has an invalid position argument!", key.c_str()); - offset.y = strtol(args[1].c_str(), &end_ptr, 10); - if (*end_ptr != '\0') - Log(EError, "Label command '%s' has an invalid position argument!", key.c_str()); - labelAnnotation = true; - - if (font == NULL) { - font = new Font(Font::EBitstreamVeraMono14); - font->convert(bitmap->getPixelFormat(), bitmap->getComponentFormat(), gamma); - } - } else { - continue; - } - - Properties::EPropertyType type = m_properties.getType(keys[i]); - if (type == Properties::EString) { - std::string value = m_properties.getString(keys[i]); - - while (true) { - char *strt; - if (!(strt = strchr((char *) value.c_str(), '$'))) - break; - - if (strncasecmp(strt, "$rendertime", 11) == 0) { - value.replace(strt-value.c_str(), 11, timeString(renderTime)); - } else if (strncasecmp(strt, "$memusage", 11) == 0) { - value.replace(strt-value.c_str(), 11, memString(getPrivateMemoryUsage())); - } else { - char *par1, *par2; - if (!(par1 = strchr(strt, '['))) - break; - if (!(par2 = strchr(par1, ']'))) - break; - - std::string propSource = value.substr(strt-value.c_str()+1, par1-strt-1); - std::string propKey = value.substr(par1-value.c_str()+1, par2-par1-1); - propSource.erase(std::remove_if(propSource.begin(), propSource.end(), ::isspace), propSource.end()); - propKey.erase(std::remove_if(propKey.begin(), propKey.end(), ::isspace), propKey.end()); - - if (!boost::starts_with(propKey, "'") || !boost::ends_with(propKey, "'")) - Log(EError, "Encountered invalid key '%s'", propKey.c_str()); - - propKey = propKey.substr(1, propKey.length()-2); - - const ConfigurableObject *source = NULL; - if (propSource == "film") - source = scene->getFilm(); - else if (propSource == "sampler") - source = scene->getSampler(); - else if (propSource == "sensor") - source = scene->getSensor(); - else if (propSource == "integrator") - source = scene->getIntegrator(); - else - Log(EError, "Unknown data source '%s' (must be film/sampler/sensor/integrator)", propSource.c_str()); - - std::string replacement; - if (propKey == "type") - replacement = source->getProperties().getPluginName(); - else - replacement = source->getProperties().getAsString(propKey); - - value.replace(strt-value.c_str(), par2-strt+1, replacement); - } - cout << value << endl; - } - if (labelAnnotation) { - Vector2i size = font->getSize(value); - bitmap->fillRect(offset-Vector2i(4, 4), size + Vector2i(8, 8), Spectrum(0.0f)); - font->drawText(bitmap, offset, value); - } else { - metadata.setString(key, value); - } - } else { - if (labelAnnotation) - Log(EError, "Only string-valued label annotations are supported!"); - metadata.copyAttribute(m_properties, keys[i], key); - } - } + annotate(scene, m_properties, bitmap, renderTime, 1.0f); /* Attach the log file to the image if this is requested */ Logger *logger = Thread::getThread()->getLogger(); @@ -477,7 +376,7 @@ public: if (m_attachLog && logger->readLog(log)) { log += "\n\n"; log += Statistics::getInstance()->getStats(); - metadata.setString("log", log); + bitmap->setMetadataString("log", log); } bitmap->write(m_fileFormat, stream); @@ -516,11 +415,6 @@ public: MTS_DECLARE_CLASS() protected: - struct Annotation { - Point2i offset; - std::string text; - }; - Bitmap::EFileFormat m_fileFormat; Bitmap::EPixelFormat m_pixelFormat; Bitmap::EComponentFormat m_componentFormat; diff --git a/src/films/ldrfilm.cpp b/src/films/ldrfilm.cpp index a2c3a62e..55ad5cab 100644 --- a/src/films/ldrfilm.cpp +++ b/src/films/ldrfilm.cpp @@ -20,9 +20,9 @@ #include #include #include -#include #include #include "banner.h" +#include "annotations.h" MTS_NAMESPACE_BEGIN @@ -185,20 +185,11 @@ public: std::vector keys = props.getPropertyNames(); for (size_t i=0; i args = tokenize(key.substr(5, key.length()-6), " ,"); - - if (args.size() != 2) - Log(EError, "Text command '%s' has an invalid number of arguments!", key.c_str()); - - Annotation annotation; - annotation.offset = Point2i(atoi(args[0].c_str()), atoi(args[1].c_str())); - annotation.text = props.getString(keys[i]); - m_annotations.push_back(annotation); - } + if ((boost::starts_with(key, "tag('") && boost::ends_with(key, "')")) || + (boost::starts_with(key, "text(") && boost::ends_with(key, ")"))) + props.markQueried(keys[i]); } m_storage = new ImageBlock(Bitmap::ESpectrumAlphaWeight, m_cropSize); @@ -338,23 +329,6 @@ public: } } - if (!m_annotations.empty()) { - ref font = new Font(Font::EBitstreamVeraMono14); - font->convert(bitmap->getPixelFormat(), bitmap->getComponentFormat(), m_gamma); - - for (size_t i=0; igetSize(text); - bitmap->fillRect(offset-Vector2i(4, 4), size + Vector2i(8, 8), Spectrum(0.0f)); - font->drawText(bitmap, offset, text); - } - } - - for (std::map::const_iterator it = m_tags.begin(); - it != m_tags.end(); ++it) - bitmap->setMetadataString(it->first, it->second); - fs::path filename = m_destFile; std::string extension = boost::to_lower_copy(filename.extension().string()); std::string expectedExtension; @@ -370,6 +344,8 @@ public: Log(EInfo, "Writing image to \"%s\" ..", filename.string().c_str()); ref stream = new FileStream(filename, FileStream::ETruncWrite); + annotate(scene, m_properties, bitmap, renderTime, m_gamma); + bitmap->write(m_fileFormat, stream); } @@ -415,11 +391,6 @@ public: MTS_DECLARE_CLASS() protected: - struct Annotation { - Point2i offset; - std::string text; - }; - Bitmap::EFileFormat m_fileFormat; Bitmap::EPixelFormat m_pixelFormat; bool m_hasBanner; @@ -428,9 +399,6 @@ protected: ref m_storage; ETonemapMethod m_tonemapMethod; Float m_exposure, m_reinhardKey, m_reinhardBurn; - - std::vector m_annotations; - std::map m_tags; }; MTS_IMPLEMENT_CLASS_S(LDRFilm, false, Film)