/*
- Copyright (C) 2012-2019 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2021 Carl Hetherington <cth@carlh.net>
This file is part of libdcp.
files in the program, then also delete it here.
*/
-#include "raw_convert.h"
-#include "types.h"
-#include "exceptions.h"
+
+/** @file src/types.cc
+ * @brief Miscellaneous types
+ */
+
+
#include "compose.hpp"
#include "dcp_assert.h"
+#include "exceptions.h"
+#include "raw_convert.h"
+#include "types.h"
+#include "warnings.h"
+LIBDCP_DISABLE_WARNINGS
#include <libxml++/libxml++.h>
+LIBDCP_ENABLE_WARNINGS
#include <boost/algorithm/string.hpp>
-#include <boost/foreach.hpp>
#include <string>
#include <vector>
#include <cmath>
#include <cstdio>
#include <iomanip>
+
using std::string;
using std::ostream;
using std::vector;
using namespace dcp;
using namespace boost;
+
bool dcp::operator== (dcp::Size const & a, dcp::Size const & b)
{
return (a.width == b.width && a.height == b.height);
}
+
bool dcp::operator!= (dcp::Size const & a, dcp::Size const & b)
{
return !(a == b);
}
-ostream& dcp::operator<< (ostream& s, dcp::Size const & a)
-{
- s << a.width << "x" << a.height;
- return s;
-}
-/** Construct a Fraction from a string of the form <numerator> <denominator>
+/** Construct a Fraction from a string of the form "numerator denominator"
* e.g. "1 3".
*/
Fraction::Fraction (string s)
vector<string> b;
split (b, s, is_any_of (" "));
if (b.size() != 2) {
- boost::throw_exception (XMLError ("malformed fraction " + s + " in XML node"));
+ boost::throw_exception (XMLError("malformed fraction " + s + " in XML node"));
}
numerator = raw_convert<int> (b[0]);
denominator = raw_convert<int> (b[1]);
}
+
string
Fraction::as_string () const
{
return String::compose ("%1 %2", numerator, denominator);
}
+
bool
dcp::operator== (Fraction const & a, Fraction const & b)
{
return (a.numerator == b.numerator && a.denominator == b.denominator);
}
+
bool
dcp::operator!= (Fraction const & a, Fraction const & b)
{
return (a.numerator != b.numerator || a.denominator != b.denominator);
}
-ostream&
-dcp::operator<< (ostream& s, Fraction const & f)
-{
- s << f.numerator << "/" << f.denominator;
- return s;
-}
-
-/** Construct a Colour, initialising it to black. */
-Colour::Colour ()
- : r (0)
- , g (0)
- , b (0)
-{
-
-}
-/** Construct a Colour from R, G and B. The values run between
- * 0 and 255.
- */
Colour::Colour (int r_, int g_, int b_)
: r (r_)
, g (g_)
}
-/** Construct a Colour from an ARGB hex string; the alpha value is ignored.
- * @param argb_hex A string of the form AARRGGBB, where e.g. RR is a two-character
- * hex value.
- */
+
Colour::Colour (string argb_hex)
{
int alpha;
}
}
-/** @return An ARGB string of the form AARRGGBB, where e.g. RR is a two-character
- * hex value. The alpha value will always be FF (ie 255; maximum alpha).
- */
+
string
Colour::to_argb_string () const
{
return buffer;
}
-/** @return An RGB string of the form RRGGBB, where e.g. RR is a two-character
- * hex value.
- */
+
string
Colour::to_rgb_string () const
{
return buffer;
}
-/** operator== for Colours.
- * @param a First colour to compare.
- * @param b Second colour to compare.
- */
+
bool
dcp::operator== (Colour const & a, Colour const & b)
{
return (a.r == b.r && a.g == b.g && a.b == b.b);
}
-/** operator!= for Colours.
- * @param a First colour to compare.
- * @param b Second colour to compare.
- */
+
bool
dcp::operator!= (Colour const & a, Colour const & b)
{
return !(a == b);
}
-ostream &
-dcp::operator<< (ostream& s, Colour const & c)
-{
- s << "(" << c.r << ", " << c.g << ", " << c.b << ")";
- return s;
-}
string
dcp::effect_to_string (Effect e)
{
switch (e) {
- case NONE:
+ case Effect::NONE:
return "none";
- case BORDER:
+ case Effect::BORDER:
return "border";
- case SHADOW:
+ case Effect::SHADOW:
return "shadow";
}
- boost::throw_exception (MiscError ("unknown effect type"));
+ boost::throw_exception (MiscError("unknown effect type"));
}
+
Effect
dcp::string_to_effect (string s)
{
if (s == "none") {
- return NONE;
+ return Effect::NONE;
} else if (s == "border") {
- return BORDER;
+ return Effect::BORDER;
} else if (s == "shadow") {
- return SHADOW;
+ return Effect::SHADOW;
}
- boost::throw_exception (ReadError ("unknown subtitle effect type"));
+ boost::throw_exception (ReadError("unknown subtitle effect type"));
}
+
string
dcp::halign_to_string (HAlign h)
{
switch (h) {
- case HALIGN_LEFT:
+ case HAlign::LEFT:
return "left";
- case HALIGN_CENTER:
+ case HAlign::CENTER:
return "center";
- case HALIGN_RIGHT:
+ case HAlign::RIGHT:
return "right";
}
- boost::throw_exception (MiscError ("unknown subtitle halign type"));
+ boost::throw_exception (MiscError("unknown subtitle halign type"));
}
+
HAlign
dcp::string_to_halign (string s)
{
if (s == "left") {
- return HALIGN_LEFT;
+ return HAlign::LEFT;
} else if (s == "center") {
- return HALIGN_CENTER;
+ return HAlign::CENTER;
} else if (s == "right") {
- return HALIGN_RIGHT;
- }
-
- boost::throw_exception (ReadError ("unknown subtitle halign type"));
-}
-
-string
-dcp::valign_to_string (VAlign v)
-{
- switch (v) {
- case VALIGN_TOP:
- return "top";
- case VALIGN_CENTER:
- return "center";
- case VALIGN_BOTTOM:
- return "bottom";
+ return HAlign::RIGHT;
}
- boost::throw_exception (MiscError ("unknown subtitle valign type"));
+ boost::throw_exception (ReadError("unknown subtitle halign type"));
}
-VAlign
-dcp::string_to_valign (string s)
-{
- if (s == "top") {
- return VALIGN_TOP;
- } else if (s == "center") {
- return VALIGN_CENTER;
- } else if (s == "bottom") {
- return VALIGN_BOTTOM;
- }
-
- boost::throw_exception (ReadError ("unknown subtitle valign type"));
-}
string
dcp::direction_to_string (Direction v)
{
switch (v) {
- case DIRECTION_LTR:
+ case Direction::LTR:
return "ltr";
- case DIRECTION_RTL:
+ case Direction::RTL:
return "rtl";
- case DIRECTION_TTB:
+ case Direction::TTB:
return "ttb";
- case DIRECTION_BTT:
+ case Direction::BTT:
return "btt";
}
- boost::throw_exception (MiscError ("unknown subtitle direction type"));
+ boost::throw_exception (MiscError("unknown subtitle direction type"));
}
+
Direction
dcp::string_to_direction (string s)
{
if (s == "ltr" || s == "horizontal") {
- return DIRECTION_LTR;
+ return Direction::LTR;
} else if (s == "rtl") {
- return DIRECTION_RTL;
+ return Direction::RTL;
} else if (s == "ttb" || s == "vertical") {
- return DIRECTION_TTB;
+ return Direction::TTB;
} else if (s == "btt") {
- return DIRECTION_BTT;
- }
-
- boost::throw_exception (ReadError ("unknown subtitle direction type"));
-}
-
-/** Convert a content kind to a string which can be used in a
- * <ContentKind> node.
- * @param kind ContentKind.
- * @return string.
- */
-string
-dcp::content_kind_to_string (ContentKind kind)
-{
- switch (kind) {
- case FEATURE:
- return "feature";
- case SHORT:
- return "short";
- case TRAILER:
- return "trailer";
- case TEST:
- return "test";
- case TRANSITIONAL:
- return "transitional";
- case RATING:
- return "rating";
- case TEASER:
- return "teaser";
- case POLICY:
- return "policy";
- case PUBLIC_SERVICE_ANNOUNCEMENT:
- return "psa";
- case ADVERTISEMENT:
- return "advertisement";
- case EPISODE:
- return "episode";
- case PROMO:
- return "promo";
+ return Direction::BTT;
}
- DCP_ASSERT (false);
+ boost::throw_exception (ReadError("unknown subtitle direction type"));
}
-/** Convert a string from a <ContentKind> node to a libdcp ContentKind.
- * Reasonably tolerant about varying case.
- * @param kind Content kind string.
- * @return libdcp ContentKind.
- */
-dcp::ContentKind
-dcp::content_kind_from_string (string kind)
-{
- transform (kind.begin(), kind.end(), kind.begin(), ::tolower);
-
- if (kind == "feature") {
- return FEATURE;
- } else if (kind == "short") {
- return SHORT;
- } else if (kind == "trailer") {
- return TRAILER;
- } else if (kind == "test") {
- return TEST;
- } else if (kind == "transitional") {
- return TRANSITIONAL;
- } else if (kind == "rating") {
- return RATING;
- } else if (kind == "teaser") {
- return TEASER;
- } else if (kind == "policy") {
- return POLICY;
- } else if (kind == "psa") {
- return PUBLIC_SERVICE_ANNOUNCEMENT;
- } else if (kind == "advertisement") {
- return ADVERTISEMENT;
- } else if (kind == "episode") {
- return EPISODE;
- } else if (kind == "promo") {
- return PROMO;
- }
-
- throw BadContentKindError (kind);
-}
string
dcp::marker_to_string (dcp::Marker m)
{
switch (m) {
- case FFOC:
+ case Marker::FFOC:
return "FFOC";
- case LFOC:
+ case Marker::LFOC:
return "LFOC";
- case FFTC:
+ case Marker::FFTC:
return "FFTC";
- case LFTC:
+ case Marker::LFTC:
return "LFTC";
- case FFOI:
+ case Marker::FFOI:
return "FFOI";
- case LFOI:
+ case Marker::LFOI:
return "LFOI";
- case FFEC:
+ case Marker::FFEC:
return "FFEC";
- case LFEC:
+ case Marker::LFEC:
return "LFEC";
- case FFMC:
+ case Marker::FFMC:
return "FFMC";
- case LFMC:
+ case Marker::LFMC:
return "LFMC";
}
DCP_ASSERT (false);
}
+
dcp::Marker
dcp::marker_from_string (string s)
{
if (s == "FFOC") {
- return FFOC;
+ return Marker::FFOC;
} else if (s == "LFOC") {
- return LFOC;
+ return Marker::LFOC;
} else if (s == "FFTC") {
- return FFTC;
+ return Marker::FFTC;
} else if (s == "LFTC") {
- return LFTC;
+ return Marker::LFTC;
} else if (s == "FFOI") {
- return FFOI;
+ return Marker::FFOI;
} else if (s == "LFOI") {
- return LFOI;
+ return Marker::LFOI;
} else if (s == "FFEC") {
- return FFEC;
+ return Marker::FFEC;
} else if (s == "LFEC") {
- return LFEC;
+ return Marker::LFEC;
} else if (s == "FFMC") {
- return FFMC;
+ return Marker::FFMC;
} else if (s == "LFMC") {
- return LFMC;
+ return Marker::LFMC;
}
DCP_ASSERT (false);
}
-Rating::Rating (cxml::ConstNodePtr node)
-{
- agency = node->string_child("Agency");
- label = node->string_child("Label");
- node->done ();
-}
-
-void
-Rating::as_xml (xmlpp::Element* parent) const
-{
- parent->add_child("Agency")->add_child_text(agency);
- parent->add_child("Label")->add_child_text(label);
-}
-
-bool
-dcp::operator== (Rating const & a, Rating const & b)
-{
- return a.agency == b.agency && a.label == b.label;
-}
-
-ostream &
-dcp::operator<< (ostream& s, Rating const & r)
-{
- s << r.agency << " " << r.label;
- return s;
-}
-
ContentVersion::ContentVersion ()
: id ("urn:uuid:" + make_uuid())
ContentVersion::ContentVersion (cxml::ConstNodePtr node)
+ : id(node->string_child("Id"))
+ , label_text(node->string_child("LabelText"))
{
- id = node->string_child("Id");
- label_text = node->string_child("LabelText");
+
}
void
ContentVersion::as_xml (xmlpp::Element* parent) const
{
- xmlpp::Node* cv = parent->add_child("ContentVersion");
+ auto cv = parent->add_child("ContentVersion");
cv->add_child("Id")->add_child_text(id);
cv->add_child("LabelText")->add_child_text(label_text);
}
Luminance::Luminance (cxml::ConstNodePtr node)
+ : _value(raw_convert<float>(node->content()))
+ , _unit(string_to_unit(node->string_attribute("units")))
{
- _unit = string_to_unit (node->string_attribute("units"));
- _value = raw_convert<float> (node->content());
+
}
void
Luminance::as_xml (xmlpp::Element* parent, string ns) const
{
- xmlpp::Element* lum = parent->add_child("Luminance", ns);
+ auto lum = parent->add_child("Luminance", ns);
lum->set_attribute("units", unit_to_string(_unit));
lum->add_child_text(raw_convert<string>(_value, 3));
}
Luminance::unit_to_string (Unit u)
{
switch (u) {
- case CANDELA_PER_SQUARE_METRE:
+ case Unit::CANDELA_PER_SQUARE_METRE:
return "candela-per-square-metre";
- case FOOT_LAMBERT:
+ case Unit::FOOT_LAMBERT:
return "foot-lambert";
default:
DCP_ASSERT (false);
}
- return "";
+ return {};
}
}
+float
+Luminance::value_in_foot_lamberts () const
+{
+ switch (_unit) {
+ case Unit::CANDELA_PER_SQUARE_METRE:
+ return _value / 3.426;
+ case Unit::FOOT_LAMBERT:
+ return _value;
+ default:
+ DCP_ASSERT (false);
+ }
+}
+
+
bool
dcp::operator== (Luminance const& a, Luminance const& b)
{
{
vector<string> parts;
boost::split (parts, s, boost::is_any_of("/"));
- if (parts.size() != 2) {
- throw MainSoundConfigurationError (s);
+ if (parts.empty()) {
+ throw MainSoundConfigurationError(s);
}
if (parts[0] == "51") {
- _field = FIVE_POINT_ONE;
+ _field = MCASoundField::FIVE_POINT_ONE;
} else if (parts[0] == "71") {
- _field = SEVEN_POINT_ONE;
+ _field = MCASoundField::SEVEN_POINT_ONE;
} else {
- throw MainSoundConfigurationError (s);
+ _field = MCASoundField::OTHER;
+ }
+
+ if (parts.size() < 2) {
+ /* I think it's OK to just have the sound field descriptor with no channels, though
+ * to me it's not clear and I might be wrong.
+ */
+ return;
}
vector<string> channels;
throw MainSoundConfigurationError (s);
}
- BOOST_FOREACH (string i, channels) {
+ for (auto i: channels) {
if (i == "-") {
_channels.push_back(optional<Channel>());
} else {
MainSoundConfiguration::to_string () const
{
string c;
- if (_field == FIVE_POINT_ONE) {
+ switch (_field) {
+ case MCASoundField::FIVE_POINT_ONE:
c = "51/";
- } else {
+ break;
+ case MCASoundField::SEVEN_POINT_ONE:
c = "71/";
+ break;
+ default:
+ DCP_ASSERT(false);
}
- BOOST_FOREACH (optional<Channel> i, _channels) {
+ for (auto i: _channels) {
if (!i) {
c += "-,";
} else {
dcp::status_to_string (Status s)
{
switch (s) {
- case FINAL:
+ case Status::FINAL:
return "final";
- case TEMP:
+ case Status::TEMP:
return "temp";
- case PRE:
+ case Status::PRE:
return "pre";
default:
DCP_ASSERT (false);
}
-
}
dcp::string_to_status (string s)
{
if (s == "final") {
- return FINAL;
+ return Status::FINAL;
} else if (s == "temp") {
- return TEMP;
+ return Status::TEMP;
} else if (s == "pre") {
- return PRE;
+ return Status::PRE;
}
DCP_ASSERT (false);
Channel
dcp::mca_id_to_channel (string id)
{
- if (id == "L") {
- return LEFT;
- } else if (id == "R") {
- return RIGHT;
- } else if (id == "C") {
- return CENTRE;
- } else if (id == "LFE") {
- return LFE;
- } else if (id == "Ls" || id == "Lss") {
- return LS;
- } else if (id == "Rs" || id == "Rss") {
- return RS;
- } else if (id == "HI") {
- return HI;
- } else if (id == "VIN") {
- return VI;
- } else if (id == "Lrs") {
- return BSL;
- } else if (id == "Rrs") {
- return BSR;
- } else if (id == "DBOX") {
- return MOTION_DATA;
- } else if (id == "FSKSync") {
- return SYNC_SIGNAL;
- } else if (id == "SLVS") {
- return SIGN_LANGUAGE;
+ transform(id.begin(), id.end(), id.begin(), ::tolower);
+
+ if (id == "l") {
+ return Channel::LEFT;
+ } else if (id == "r") {
+ return Channel::RIGHT;
+ } else if (id == "c") {
+ return Channel::CENTRE;
+ } else if (id == "lfe") {
+ return Channel::LFE;
+ } else if (id == "ls" || id == "lss") {
+ return Channel::LS;
+ } else if (id == "rs" || id == "rss") {
+ return Channel::RS;
+ } else if (id == "hi") {
+ return Channel::HI;
+ } else if (id == "vin") {
+ return Channel::VI;
+ } else if (id == "lrs") {
+ return Channel::BSL;
+ } else if (id == "rrs") {
+ return Channel::BSR;
+ } else if (id == "dbox") {
+ return Channel::MOTION_DATA;
+ } else if (id == "sync" || id == "fsksync") {
+ return Channel::SYNC_SIGNAL;
+ } else if (id == "slvs") {
+ return Channel::SIGN_LANGUAGE;
}
throw UnknownChannelIdError (id);
dcp::channel_to_mca_id (Channel c, MCASoundField field)
{
switch (c) {
- case LEFT:
+ case Channel::LEFT:
return "L";
- case RIGHT:
+ case Channel::RIGHT:
return "R";
- case CENTRE:
+ case Channel::CENTRE:
return "C";
- case LFE:
+ case Channel::LFE:
return "LFE";
- case LS:
- return field == FIVE_POINT_ONE ? "Ls" : "Lss";
- case RS:
- return field == FIVE_POINT_ONE ? "Rs" : "Rss";
- case HI:
+ case Channel::LS:
+ return field == MCASoundField::FIVE_POINT_ONE ? "Ls" : "Lss";
+ case Channel::RS:
+ return field == MCASoundField::FIVE_POINT_ONE ? "Rs" : "Rss";
+ case Channel::HI:
return "HI";
- case VI:
+ case Channel::VI:
return "VIN";
- case BSL:
+ case Channel::BSL:
return "Lrs";
- case BSR:
+ case Channel::BSR:
return "Rrs";
- case MOTION_DATA:
+ case Channel::MOTION_DATA:
return "DBOX";
- case SYNC_SIGNAL:
+ case Channel::SYNC_SIGNAL:
return "FSKSync";
- case SIGN_LANGUAGE:
+ case Channel::SIGN_LANGUAGE:
return "SLVS";
default:
break;
dcp::channel_to_mca_name (Channel c, MCASoundField field)
{
switch (c) {
- case LEFT:
+ case Channel::LEFT:
return "Left";
- case RIGHT:
+ case Channel::RIGHT:
return "Right";
- case CENTRE:
+ case Channel::CENTRE:
return "Center";
- case LFE:
+ case Channel::LFE:
return "LFE";
- case LS:
- return field == FIVE_POINT_ONE ? "Left Surround" : "Left Side Surround";
- case RS:
- return field == FIVE_POINT_ONE ? "Right Surround" : "Right Side Surround";
- case HI:
+ case Channel::LS:
+ return field == MCASoundField::FIVE_POINT_ONE ? "Left Surround" : "Left Side Surround";
+ case Channel::RS:
+ return field == MCASoundField::FIVE_POINT_ONE ? "Right Surround" : "Right Side Surround";
+ case Channel::HI:
return "Hearing Impaired";
- case VI:
+ case Channel::VI:
return "Visually Impaired-Narrative";
- case BSL:
+ case Channel::BSL:
return "Left Rear Surround";
- case BSR:
+ case Channel::BSR:
return "Right Rear Surround";
- case MOTION_DATA:
+ case Channel::MOTION_DATA:
return "D-BOX Motion Code Primary Stream";
- case SYNC_SIGNAL:
+ case Channel::SYNC_SIGNAL:
return "FSK Sync";
- case SIGN_LANGUAGE:
+ case Channel::SIGN_LANGUAGE:
return "Sign Language Video Stream";
default:
break;
};
switch (c) {
- case LEFT:
+ case Channel::LEFT:
return dict->ul(ASDCP::MDD_DCAudioChannel_L);
- case RIGHT:
+ case Channel::RIGHT:
return dict->ul(ASDCP::MDD_DCAudioChannel_R);
- case CENTRE:
+ case Channel::CENTRE:
return dict->ul(ASDCP::MDD_DCAudioChannel_C);
- case LFE:
+ case Channel::LFE:
return dict->ul(ASDCP::MDD_DCAudioChannel_LFE);
- case LS:
- return dict->ul(field == FIVE_POINT_ONE ? ASDCP::MDD_DCAudioChannel_Ls : ASDCP::MDD_DCAudioChannel_Lss);
- case RS:
- return dict->ul(field == FIVE_POINT_ONE ? ASDCP::MDD_DCAudioChannel_Rs : ASDCP::MDD_DCAudioChannel_Rss);
- case HI:
+ case Channel::LS:
+ return dict->ul(field == MCASoundField::FIVE_POINT_ONE ? ASDCP::MDD_DCAudioChannel_Ls : ASDCP::MDD_DCAudioChannel_Lss);
+ case Channel::RS:
+ return dict->ul(field == MCASoundField::FIVE_POINT_ONE ? ASDCP::MDD_DCAudioChannel_Rs : ASDCP::MDD_DCAudioChannel_Rss);
+ case Channel::HI:
return dict->ul(ASDCP::MDD_DCAudioChannel_HI);
- case VI:
+ case Channel::VI:
return dict->ul(ASDCP::MDD_DCAudioChannel_VIN);
- case BSL:
+ case Channel::BSL:
return dict->ul(ASDCP::MDD_DCAudioChannel_Lrs);
- case BSR:
+ case Channel::BSR:
return dict->ul(ASDCP::MDD_DCAudioChannel_Rrs);
- case MOTION_DATA:
+ case Channel::MOTION_DATA:
return dict->ul(ASDCP::MDD_DBOXMotionCodePrimaryStream);
- case SYNC_SIGNAL:
+ case Channel::SYNC_SIGNAL:
return ASDCP::UL(sync_signal);
- case SIGN_LANGUAGE:
+ case Channel::SIGN_LANGUAGE:
return ASDCP::UL(sign_language);
default:
break;
vector<dcp::Channel>
dcp::used_audio_channels ()
{
- vector<dcp::Channel> c;
- c.push_back (LEFT);
- c.push_back (RIGHT);
- c.push_back (CENTRE);
- c.push_back (LFE);
- c.push_back (LS);
- c.push_back (RS);
- c.push_back (HI);
- c.push_back (VI);
- c.push_back (BSL);
- c.push_back (BSR);
- c.push_back (MOTION_DATA);
- c.push_back (SYNC_SIGNAL);
- c.push_back (SIGN_LANGUAGE);
- return c;
+ return {
+ Channel::LEFT,
+ Channel::RIGHT,
+ Channel::CENTRE,
+ Channel::LFE,
+ Channel::LS,
+ Channel::RS,
+ Channel::HI,
+ Channel::VI,
+ Channel::BSL,
+ Channel::BSR,
+ Channel::MOTION_DATA,
+ Channel::SYNC_SIGNAL,
+ Channel::SIGN_LANGUAGE
+ };
+}
+
+
+string
+dcp::formulation_to_string (dcp::Formulation formulation)
+{
+ switch (formulation) {
+ case Formulation::MODIFIED_TRANSITIONAL_1:
+ return "modified-transitional-1";
+ case Formulation::MULTIPLE_MODIFIED_TRANSITIONAL_1:
+ return "multiple-modified-transitional-1";
+ case Formulation::DCI_ANY:
+ return "dci-any";
+ case Formulation::DCI_SPECIFIC:
+ return "dci-specific";
+ }
+
+ DCP_ASSERT (false);
+}
+
+
+dcp::Formulation
+dcp::string_to_formulation (string formulation)
+{
+ if (formulation == "modified-transitional-1") {
+ return Formulation::MODIFIED_TRANSITIONAL_1;
+ } else if (formulation == "multiple-modified-transitional-1") {
+ return Formulation::MULTIPLE_MODIFIED_TRANSITIONAL_1;
+ } else if (formulation == "dci-any") {
+ return Formulation::DCI_ANY;
+ } else if (formulation == "dci-specific") {
+ return Formulation::DCI_SPECIFIC;
+ }
+
+ DCP_ASSERT (false);
}