}
//
-static Kumu::UUID
-create_png_name_id(const std::string& image_name)
+Kumu::UUID
+AS_02::TimedText::CreatePNGNameId(const std::string& image_name)
{
return create_4122_type5_id(image_name, s_png_id_prefix);
}
//
-static Kumu::UUID
-create_font_name_id(const std::string& font_name)
+Kumu::UUID
+AS_02::TimedText::CreateFontNameId(const std::string& font_name)
{
return create_4122_type5_id(font_name, s_font_id_prefix);
}
static void
setup_default_font_family_list()
{
+ AutoMutex l(sg_default_font_family_list_lock);
sg_default_font_family_list.insert("default");
sg_default_font_family_list.insert("monospace");
sg_default_font_family_list.insert("sansSerif");
// is it PNG?
if ( memcmp(read_buffer, PNGMagic, sizeof(PNGMagic)) == 0 )
{
- UUID asset_id = create_png_name_id(next_item);
+ UUID asset_id = CreatePNGNameId(PathBasename(next_item));
m_ResourceMap.insert(ResourceMap::value_type(asset_id, next_item));
}
// is it a font?
|| memcmp(read_buffer, TrueTypeMagic, sizeof(TrueTypeMagic)) == 0 )
{
std::string font_root_name = PathSetExtension(next_item, "");
- UUID asset_id = create_font_name_id(font_root_name);
+ UUID asset_id = CreateFontNameId(PathBasename(font_root_name));
m_ResourceMap.insert(ResourceMap::value_type(asset_id, next_item));
}
}
{
XMLElement m_Root;
ResourceTypeMap_t m_ResourceTypes;
- Result_t OpenRead(const std::string& profile_name);
+ Result_t OpenRead();
ASDCP_NO_COPY_CONSTRUCT(h__TextParser);
return m_DefaultResolver;
}
- Result_t OpenRead(const std::string& filename, const std::string& profile_name);
- Result_t OpenRead(const std::string& xml_doc, const std::string& filename, const std::string& profile_name);
+ Result_t OpenRead(const std::string& filename);
+ Result_t OpenRead(const std::string& xml_doc, const std::string& filename);
Result_t ReadAncillaryResource(const byte_t *uuid, ASDCP::TimedText::FrameBuffer& FrameBuf,
const ASDCP::TimedText::IResourceResolver& Resolver) const;
};
//
Result_t
-AS_02::TimedText::ST2052_TextParser::h__TextParser::OpenRead(const std::string& filename, const std::string& profile_name)
+AS_02::TimedText::ST2052_TextParser::h__TextParser::OpenRead(const std::string& filename)
{
Result_t result = ReadFileIntoString(filename, m_XMLDoc);
if ( KM_SUCCESS(result) )
{
m_Filename = filename;
- result = OpenRead(profile_name);
+ result = OpenRead();
}
return result;
//
Result_t
-AS_02::TimedText::ST2052_TextParser::h__TextParser::OpenRead(const std::string& xml_doc, const std::string& filename,
- const std::string& profile_name)
+AS_02::TimedText::ST2052_TextParser::h__TextParser::OpenRead(const std::string& xml_doc, const std::string& filename)
{
m_XMLDoc = xml_doc;
m_Filename = filename;
- return OpenRead(profile_name);
+ return OpenRead();
}
-//
-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
-AS_02::TimedText::ST2052_TextParser::h__TextParser::OpenRead(const std::string& profile_name)
+AS_02::TimedText::ST2052_TextParser::h__TextParser::OpenRead()
{
setup_default_font_family_list();
m_TDesc.EncodingName = "UTF-8"; // the XML parser demands UTF-8
m_TDesc.ResourceList.clear();
m_TDesc.ContainerDuration = 0;
- m_TDesc.NamespaceName = profile_name;
+ 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 )
{
- UUID asset_id = create_png_name_id(*i);
+ UUID asset_id = CreatePNGNameId(PathBasename(*i));
TimedTextResourceDescriptor png_resource;
memcpy(png_resource.ResourceID, asset_id.Value(), UUIDlen);
png_resource.Type = ASDCP::TimedText::MT_PNG;
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];
for ( i = font_visitor.value_list.begin(); i != font_visitor.value_list.end(); ++i )
{
- UUID font_id = create_font_name_id(*i);
+ UUID font_id = CreateFontNameId(PathBasename(*i));
if ( PathIsFile(font_id.EncodeHex(buf, 64))
|| PathIsFile(*i+".ttf")
// Opens the stream for reading, parses enough data to provide a complete
// set of stream metadata for the MXFWriter below.
ASDCP::Result_t
-AS_02::TimedText::ST2052_TextParser::OpenRead(const std::string& filename, const std::string& profile_name) const
+AS_02::TimedText::ST2052_TextParser::OpenRead(const std::string& filename) const
{
const_cast<AS_02::TimedText::ST2052_TextParser*>(this)->m_Parser = new h__TextParser;
- Result_t result = m_Parser->OpenRead(filename, profile_name);
+ Result_t result = m_Parser->OpenRead(filename);
if ( ASDCP_FAILURE(result) )
const_cast<AS_02::TimedText::ST2052_TextParser*>(this)->m_Parser = 0;
// Parses an XML document to provide a complete set of stream metadata for the MXFWriter below.
Result_t
-AS_02::TimedText::ST2052_TextParser::OpenRead(const std::string& xml_doc, const std::string& filename,
- const std::string& profile_name) const
+AS_02::TimedText::ST2052_TextParser::OpenRead(const std::string& xml_doc, const std::string& filename) const
{
const_cast<AS_02::TimedText::ST2052_TextParser*>(this)->m_Parser = new h__TextParser;
- Result_t result = m_Parser->OpenRead(xml_doc, filename, profile_name);
+ Result_t result = m_Parser->OpenRead(xml_doc, filename);
if ( ASDCP_FAILURE(result) )
const_cast<AS_02::TimedText::ST2052_TextParser*>(this)->m_Parser = 0;