summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjhurst <jhurst@cinecert.com>2016-12-07 18:11:32 +0000
committerjhurst <>2016-12-07 18:11:32 +0000
commitdec4ef68baee633aac30f4b3e0aab6553c22f967 (patch)
treedc4f1bbdc6023604ec380393eebd1aebaae3236d /src
parent74e6b1105dffe52c6f347d723507ab346eabbb5a (diff)
o Improved IMSC-1 profile detection. May not yet be perfect, experimentation
encouraged! o Refactored XML element & attribute visitation to KM_xml.h o Added km_join() template to KM_util.h
Diffstat (limited to 'src')
-rwxr-xr-xsrc/KM_util.h21
-rw-r--r--src/KM_xml.h72
-rw-r--r--src/ST2052_TextParser.cpp106
3 files changed, 150 insertions, 49 deletions
diff --git a/src/KM_util.h b/src/KM_util.h
index 4834891..e8004c1 100755
--- a/src/KM_util.h
+++ b/src/KM_util.h
@@ -543,6 +543,27 @@ namespace Kumu
// adjacent instances of the separator. E.g., "/foo//bar/" will return ["", "foo", "", "bar", ""].
std::list<std::string> km_token_split(const std::string& str, const std::string& separator);
+ // Join the tokens in the given list using delimiter. If prefix is defined then each token
+ // will be concatenated with the prefix before being added to the composite string.
+ template <class T>
+ std::string
+ km_join(const T& list, const std::string& delimiter, const std::string& prefix = "")
+ {
+ std::string result;
+
+ for ( typename T::const_iterator i = list.begin(); i != list.end(); ++i )
+ {
+ if ( i != list.begin() )
+ {
+ result += delimiter;
+ }
+
+ result += prefix + *i;
+ }
+
+ return result;
+ }
+
} // namespace Kumu
diff --git a/src/KM_xml.h b/src/KM_xml.h
index 0c84e56..120857c 100644
--- a/src/KM_xml.h
+++ b/src/KM_xml.h
@@ -35,6 +35,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <KM_util.h>
#include <list>
+#include <set>
#include <string>
namespace Kumu
@@ -143,6 +144,77 @@ namespace Kumu
void DeleteChild(const XMLElement* element);
void ForgetChild(const XMLElement* element);
};
+
+ //
+ template <class VisitorType>
+ bool
+ apply_visitor(const XMLElement& element, VisitorType& visitor)
+ {
+ const ElementList& l = element.GetChildren();
+ ElementList::const_iterator i;
+
+ for ( i = l.begin(); i != l.end(); ++i )
+ {
+ if ( ! visitor.Element(**i) )
+ {
+ return false;
+ }
+
+ if ( ! apply_visitor(**i, visitor) )
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ //
+ class AttributeVisitor
+ {
+ std::string attr_name;
+
+ public:
+ AttributeVisitor(const std::string& n) : attr_name(n) {}
+ std::set<std::string> value_list;
+
+ bool Element(const XMLElement& e)
+ {
+ const AttributeList& l = e.GetAttributes();
+ AttributeList::const_iterator i;
+
+ for ( i = l.begin(); i != l.end(); ++i )
+ {
+ if ( i->name == attr_name )
+ {
+ value_list.insert(i->value);
+ }
+ }
+
+ return true;
+ }
+ };
+
+ //
+ class ElementVisitor
+ {
+ std::string element_name;
+
+ public:
+ ElementVisitor(const std::string& n) : element_name(n) {}
+ std::set<std::string> value_list;
+
+ bool Element(const XMLElement& e)
+ {
+ if ( e.GetBody() == element_name )
+ {
+ value_list.insert(e.GetBody());
+ }
+
+ return true;
+ }
+ };
+
} // namespace Kumu
#endif // _KM_XML_H_
diff --git a/src/ST2052_TextParser.cpp b/src/ST2052_TextParser.cpp
index f291a1b..a98b4ca 100644
--- a/src/ST2052_TextParser.cpp
+++ b/src/ST2052_TextParser.cpp
@@ -290,55 +290,10 @@ AS_02::TimedText::ST2052_TextParser::h__TextParser::OpenRead(const std::string&
return OpenRead(profile_name);
}
-//
-template <class VisitorType>
-bool
-apply_visitor(const XMLElement& element, VisitorType& visitor)
-{
- const ElementList& l = element.GetChildren();
- ElementList::const_iterator i;
-
- for ( i = l.begin(); i != l.end(); ++i )
- {
- if ( ! visitor.Element(**i) )
- {
- return false;
- }
-
- if ( ! apply_visitor(**i, visitor) )
- {
- return false;
- }
- }
-
- return true;
-}
-//
-class AttributeVisitor
-{
- std::string attr_name;
-
-public:
- AttributeVisitor(const std::string& n) : attr_name(n) {}
- std::set<std::string> value_list;
-
- bool Element(const XMLElement& e)
- {
- const AttributeList& l = e.GetAttributes();
- AttributeList::const_iterator i;
-
- for ( i = l.begin(); i != l.end(); ++i )
- {
- if ( i->name == attr_name )
- {
- value_list.insert(i->value);
- }
- }
- return true;
- }
-};
+std::string const IMSC1_imageProfile = "http://www.w3.org/ns/ttml/profile/imsc1/image";
+std::string const IMSC1_textProfile = "http://www.w3.org/ns/ttml/profile/imsc1/text";
//
Result_t
@@ -355,11 +310,45 @@ AS_02::TimedText::ST2052_TextParser::h__TextParser::OpenRead(const std::string&
m_TDesc.EncodingName = "UTF-8"; // the XML parser demands UTF-8
m_TDesc.ResourceList.clear();
m_TDesc.ContainerDuration = 0;
- m_TDesc.NamespaceName = profile_name;
+ m_TDesc.NamespaceName = profile_name; // set the profile explicitly
+ std::set<std::string>::const_iterator i;
+
+ // Attempt to set the profile from <conformsToStandard>
+ if ( m_TDesc.NamespaceName.empty() )
+ {
+ ElementVisitor conforms_visitor("conformsToStandard");
+ apply_visitor(m_Root, conforms_visitor);
+
+ for ( i = conforms_visitor.value_list.begin(); i != conforms_visitor.value_list.end(); ++i )
+ {
+ if ( *i == IMSC1_imageProfile || *i == IMSC1_textProfile )
+ {
+ m_TDesc.NamespaceName = *i;
+ break;
+ }
+ }
+ }
+
+ // Attempt to set the profile from the use of attribute "profile"
+ if ( m_TDesc.NamespaceName.empty() )
+ {
+ AttributeVisitor profile_visitor("profile");
+ apply_visitor(m_Root, profile_visitor);
+
+ for ( i = profile_visitor.value_list.begin(); i != profile_visitor.value_list.end(); ++i )
+ {
+ if ( *i == IMSC1_imageProfile || *i == IMSC1_textProfile )
+ {
+ m_TDesc.NamespaceName = *i;
+ break;
+ }
+ }
+ }
+ // Find image resources for later packaging as GS partitions.
+ // Attempt to set the profile; infer from use of images.
AttributeVisitor png_visitor("backgroundImage");
apply_visitor(m_Root, png_visitor);
- std::set<std::string>::const_iterator i;
for ( i = png_visitor.value_list.begin(); i != png_visitor.value_list.end(); ++i )
{
@@ -370,8 +359,27 @@ AS_02::TimedText::ST2052_TextParser::h__TextParser::OpenRead(const std::string&
m_TDesc.ResourceList.push_back(png_resource);
m_ResourceTypes.insert(ResourceTypeMap_t::value_type(UUID(png_resource.ResourceID),
ASDCP::TimedText::MT_PNG));
+
+ if ( m_TDesc.NamespaceName.empty() )
+ {
+ m_TDesc.NamespaceName = IMSC1_imageProfile;
+ }
+ }
+
+ // If images are present and profile is "text" make sure to say something.
+ if ( ! m_ResourceTypes.empty() && m_TDesc.NamespaceName == IMSC1_textProfile )
+ {
+ DefaultLogSink().Warn("Unexpected IMSC-1 text profile; document contains images.\n ");
+ }
+
+ // If all else fails set the profile to "text".
+ if ( m_TDesc.NamespaceName.empty() )
+ {
+ DefaultLogSink().Warn("Using default IMSC-1 text profile.\n ");
+ m_TDesc.NamespaceName = IMSC1_textProfile;
}
+ // Find font resources for later packaging as GS partitions.
AttributeVisitor font_visitor("fontFamily");
apply_visitor(m_Root, font_visitor);
char buf[64];