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)