Merged 2378

This commit is contained in:
Moritz Bunkus 2004-10-17 19:33:15 +00:00
parent 3835e9083a
commit 6982f68026
7 changed files with 350 additions and 215 deletions

280
src/common/tag_common.cpp Normal file
View File

@ -0,0 +1,280 @@
/*
* mkvmerge -- utility for splicing together matroska files
* from component media subtypes
*
* Distributed under the GPL
* see the file COPYING for details
* or visit http://www.gnu.org/copyleft/gpl.html
*
* $Id$
*
* tag helper functions
*
* Written by Moritz Bunkus <moritz@bunkus.org>.
*/
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <vector>
#include "chapters.h"
#include "common.h"
#include "commonebml.h"
#include "matroska.h"
#include "tag_common.h"
#include <matroska/KaxTags.h>
#include <matroska/KaxTag.h>
using namespace std;
using namespace libebml;
using namespace libmatroska;
void
fix_mandatory_tag_elements(EbmlElement *e) {
if (dynamic_cast<KaxTagSimple *>(e) != NULL) {
KaxTagSimple &s = *static_cast<KaxTagSimple *>(e);
GetChild<KaxTagLangue>(s);
GetChild<KaxTagDefault>(s);
} else if (dynamic_cast<KaxTagTargets *>(e) != NULL) {
KaxTagTargets &t = *static_cast<KaxTagTargets *>(e);
GetChild<KaxTagTargetTypeValue>(t);
}
if (dynamic_cast<EbmlMaster *>(e) != NULL) {
EbmlMaster *m;
int i;
m = static_cast<EbmlMaster *>(e);
for (i = 0; i < m->ListSize(); i++)
fix_mandatory_tag_elements((*m)[i]);
}
}
KaxTags *
select_tags_for_chapters(KaxTags &tags,
KaxChapters &chapters) {
KaxTags *new_tags;
KaxTagTargets *targets;
KaxTagEditionUID *t_euid;
KaxTagChapterUID *t_cuid;
int tags_idx, targets_idx;
bool copy;
new_tags = NULL;
for (tags_idx = 0; tags_idx < tags.ListSize(); tags_idx++) {
if (dynamic_cast<KaxTag *>(tags[tags_idx]) == NULL)
continue;
copy = true;
targets = FINDFIRST(static_cast<EbmlMaster *>(tags[tags_idx]),
KaxTagTargets);
if (targets != NULL) {
for (targets_idx = 0; targets_idx < targets->ListSize(); targets_idx++) {
t_euid = dynamic_cast<KaxTagEditionUID *>((*targets)[targets_idx]);
if ((t_euid != NULL) &&
(find_edition_with_uid(chapters, uint64(*t_euid)) == NULL)) {
copy = false;
break;
}
t_cuid = dynamic_cast<KaxTagChapterUID *>((*targets)[targets_idx]);
if ((t_cuid != NULL) &&
(find_chapter_with_uid(chapters, uint64(*t_cuid)) == NULL)) {
copy = false;
break;
}
}
}
if (copy) {
if (new_tags == NULL)
new_tags = new KaxTags;
new_tags->PushElement(*(tags[tags_idx]->Clone()));
}
}
return new_tags;
}
KaxTagSimple &
find_simple_tag(const string &name,
EbmlMaster &m) {
return find_simple_tag(cstrutf8_to_UTFstring(name), m);
}
KaxTagSimple &
find_simple_tag(const UTFstring &name,
EbmlMaster &m) {
int i;
string rvalue;
if (EbmlId(m) == KaxTagSimple::ClassInfos.GlobalId) {
KaxTagName *tname;
tname = FINDFIRST(&m, KaxTagName);
if ((tname != NULL) &&
(name == UTFstring(*static_cast<EbmlUnicodeString *>(tname))))
return *static_cast<KaxTagSimple *>(&m);
}
for (i = 0; i < m.ListSize(); i++)
if ((EbmlId(*m[i]) == KaxTag::ClassInfos.GlobalId) ||
(EbmlId(*m[i]) == KaxTagSimple::ClassInfos.GlobalId)) {
try {
return find_simple_tag(name, *static_cast<EbmlMaster *>(m[i]));
} catch (...) {
}
}
throw "";
}
string
get_simple_tag_value(const string &name,
EbmlMaster &m) {
try {
KaxTagSimple &simple = find_simple_tag(name, m);
KaxTagString *tvalue;
tvalue = FINDFIRST(&simple, KaxTagString);
if (tvalue != NULL)
return UTFstring_to_cstrutf8(UTFstring(*static_cast<EbmlUnicodeString *>
(tvalue)));
} catch (...) {
}
return "";
}
string
get_simple_tag_name(const KaxTagSimple &tag) {
KaxTagName *tname;
tname = FINDFIRST(&tag, KaxTagName);
if (tname == NULL)
return "";
return UTFstring_to_cstrutf8(UTFstring(*static_cast<EbmlUnicodeString *>
(tname)));
}
string
get_simple_tag_value(const KaxTagSimple &tag) {
KaxTagString *tstring;
tstring = FINDFIRST(&tag, KaxTagString);
if (tstring == NULL)
return "";
return UTFstring_to_cstrutf8(UTFstring(*static_cast<EbmlUnicodeString *>
(tstring)));
}
void
set_simple_tag_name(KaxTagSimple &tag,
const string &name) {
*static_cast<EbmlUnicodeString *>(&GetChild<KaxTagName>(tag)) =
cstrutf8_to_UTFstring(name);
}
void
set_simple_tag_value(KaxTagSimple &tag,
const string &value) {
*static_cast<EbmlUnicodeString *>(&GetChild<KaxTagString>(tag)) =
cstrutf8_to_UTFstring(value);
}
void
set_simple_tag(KaxTagSimple &tag,
const string &name,
const string &value) {
set_simple_tag_name(tag, name);
set_simple_tag_value(tag, value);
}
int64_t
get_tag_tuid(const KaxTag &tag) {
KaxTagTargets *targets;
KaxTagTrackUID *tuid;
targets = FINDFIRST(&tag, KaxTagTargets);
if (targets == NULL)
return -1;
tuid = FINDFIRST(targets, KaxTagTrackUID);
if (tuid == NULL)
return -1;
return uint64(*static_cast<EbmlUInteger *>(tuid));
}
int64_t
get_tag_cuid(const KaxTag &tag) {
KaxTagTargets *targets;
KaxTagChapterUID *cuid;
targets = FINDFIRST(&tag, KaxTagTargets);
if (targets == NULL)
return -1;
cuid = FINDFIRST(targets, KaxTagChapterUID);
if (cuid == NULL)
return -1;
return uint64(*static_cast<EbmlUInteger *>(cuid));
}
/** \brief Convert older tags to current specs
*/
void
convert_old_tags(KaxTags &tags) {
string name, value;
int i, tags_idx, target_type_value;
bool has_level_type;
try {
find_simple_tag("LEVEL_TYPE", tags);
has_level_type = true;
} catch (...) {
has_level_type = false;
}
for (tags_idx = 0; tags_idx < tags.ListSize(); tags_idx++) {
if (!is_id(tags[tags_idx], KaxTag))
continue;
KaxTag &tag = *static_cast<KaxTag *>(tags[tags_idx]);
target_type_value = TAG_TARGETTYPE_TRACK;
i = 0;
while (i < tag.ListSize()) {
i++;
if (!is_id(tag[i - 1], KaxTagSimple))
continue;
KaxTagSimple &simple = *static_cast<KaxTagSimple *>(tag[i - 1]);
name = get_simple_tag_name(simple);
value = get_simple_tag_value(simple);
if (name == "CATALOG")
set_simple_tag_name(simple, "CATALOG_NUMBER");
else if (name == "DATE")
set_simple_tag_name(simple, "DATE_RELEASED");
else if (name == "LEVEL_TYPE") {
if (value == "MEDIA")
target_type_value = TAG_TARGETTYPE_ALBUM;
i--;
delete tag[i];
tag.Remove(i);
}
}
if (has_level_type) {
KaxTagTargets *targets;
targets = FINDFIRST(&tag, KaxTagTargets);
if (targets != NULL)
*static_cast<EbmlUInteger *>
(&GetChild<KaxTagTargetTypeValue>(*targets)) = target_type_value;
}
}
}

61
src/common/tag_common.h Normal file
View File

@ -0,0 +1,61 @@
/*
* mkvmerge -- utility for splicing together matroska files
* from component media subtypes
*
* Distributed under the GPL
* see the file COPYING for details
* or visit http://www.gnu.org/copyleft/gpl.html
*
* $Id$
*
* definition of functions helping dealing with tags
*
* Written by Moritz Bunkus <moritz@bunkus.org>.
*/
#ifndef __TAG_COMMON_H
#define __TAG_COMMON_H
#include "os.h"
#include <string>
namespace libmatroska {
class KaxTags;
class KaxTag;
class KaxTagSimple;
class KaxChapters;
};
namespace libebml {
class EbmlElement;
class EbmlMaster;
};
using namespace std;
using namespace libebml;
using namespace libmatroska;
void MTX_DLL_API fix_mandatory_tag_elements(EbmlElement *e);
KaxTags *MTX_DLL_API select_tags_for_chapters(KaxTags &tags,
KaxChapters &chapters);
KaxTagSimple &MTX_DLL_API find_simple_tag(const string &name, EbmlMaster &m);
KaxTagSimple &MTX_DLL_API find_simple_tag(const UTFstring &name,
EbmlMaster &m);
string MTX_DLL_API get_simple_tag_value(const string &name, EbmlMaster &m);
int64_t MTX_DLL_API get_tag_tuid(const KaxTag &tag);
int64_t MTX_DLL_API get_tag_cuid(const KaxTag &tag);
string MTX_DLL_API get_simple_tag_name(const KaxTagSimple &tag);
string MTX_DLL_API get_simple_tag_value(const KaxTagSimple &tag);
void MTX_DLL_API set_simple_tag_name(KaxTagSimple &tag, const string &name);
void MTX_DLL_API set_simple_tag_value(KaxTagSimple &tag, const string &value);
void MTX_DLL_API set_simple_tag(KaxTagSimple &tag, const string &name,
const string &valuevalue);
void MTX_DLL_API convert_old_tags(KaxTags &tags);
#endif // __TAG_COMMON_H

View File

@ -8,7 +8,7 @@
*
* $Id$
*
* XML tag parser. Functions for the start tags + helper functions
* XML tag parser
*
* Written by Moritz Bunkus <moritz@bunkus.org>.
*/
@ -22,7 +22,6 @@
#include <string>
#include <vector>
#include "chapters.h"
#include "common.h"
#include "commonebml.h"
#include "error.h"
@ -90,70 +89,3 @@ parse_xml_tags(const char *name,
delete in;
}
void
fix_mandatory_tag_elements(EbmlElement *e) {
if (dynamic_cast<KaxTagSimple *>(e) != NULL) {
KaxTagSimple &s = *static_cast<KaxTagSimple *>(e);
GetChild<KaxTagLangue>(s);
GetChild<KaxTagDefault>(s);
} else if (dynamic_cast<KaxTagTargets *>(e) != NULL) {
KaxTagTargets &t = *static_cast<KaxTagTargets *>(e);
GetChild<KaxTagTargetTypeValue>(t);
}
if (dynamic_cast<EbmlMaster *>(e) != NULL) {
EbmlMaster *m;
int i;
m = static_cast<EbmlMaster *>(e);
for (i = 0; i < m->ListSize(); i++)
fix_mandatory_tag_elements((*m)[i]);
}
}
KaxTags *
select_tags_for_chapters(KaxTags &tags,
KaxChapters &chapters) {
KaxTags *new_tags;
KaxTagTargets *targets;
KaxTagEditionUID *t_euid;
KaxTagChapterUID *t_cuid;
int tags_idx, targets_idx;
bool copy;
new_tags = NULL;
for (tags_idx = 0; tags_idx < tags.ListSize(); tags_idx++) {
if (dynamic_cast<KaxTag *>(tags[tags_idx]) == NULL)
continue;
copy = true;
targets = FINDFIRST(static_cast<EbmlMaster *>(tags[tags_idx]),
KaxTagTargets);
if (targets != NULL) {
for (targets_idx = 0; targets_idx < targets->ListSize(); targets_idx++) {
t_euid = dynamic_cast<KaxTagEditionUID *>((*targets)[targets_idx]);
if ((t_euid != NULL) &&
(find_edition_with_uid(chapters, uint64(*t_euid)) == NULL)) {
copy = false;
break;
}
t_cuid = dynamic_cast<KaxTagChapterUID *>((*targets)[targets_idx]);
if ((t_cuid != NULL) &&
(find_chapter_with_uid(chapters, uint64(*t_cuid)) == NULL)) {
copy = false;
break;
}
}
}
if (copy) {
if (new_tags == NULL)
new_tags = new KaxTags;
new_tags->PushElement(*(tags[tags_idx]->Clone()));
}
}
return new_tags;
}

View File

@ -18,21 +18,10 @@
namespace libmatroska {
class KaxTags;
class KaxChapters;
};
namespace libebml {
class EbmlElement;
};
using namespace libebml;
using namespace libmatroska;
void MTX_DLL_API parse_xml_tags(const char *name, KaxTags *tags);
void MTX_DLL_API fix_mandatory_tag_elements(EbmlElement *e);
KaxTags *MTX_DLL_API select_tags_for_chapters(KaxTags &tags,
KaxChapters &chapters);
#endif // __TAGPARSER_H

View File

@ -55,79 +55,11 @@ extern "C" {
#include "mkvextract.h"
#include "mm_io.h"
#include "quickparser.h"
#include "tag_common.h"
using namespace libmatroska;
using namespace std;
static string
get_simple_tag(const char *name,
EbmlMaster &m) {
int i;
UTFstring uname;
string rvalue;
uname = cstrutf8_to_UTFstring(name);
for (i = 0; i < m.ListSize(); i++)
if (EbmlId(*m[i]) == KaxTagSimple::ClassInfos.GlobalId) {
KaxTagName *tname;
UTFstring utname;
tname = FINDFIRST(m[i], KaxTagName);
if (tname == NULL)
continue;
utname = UTFstring(*static_cast<EbmlUnicodeString *>(tname));
if (utname == uname) {
KaxTagString *tvalue;
tvalue = FINDFIRST(m[i], KaxTagString);
if (tvalue != NULL)
return
UTFstring_to_cstrutf8(UTFstring(*static_cast<EbmlUnicodeString *>
(tvalue)));
else
return "";
}
}
for (i = 0; i < m.ListSize(); i++)
if ((EbmlId(*m[i]) == KaxTag::ClassInfos.GlobalId) ||
(EbmlId(*m[i]) == KaxTagSimple::ClassInfos.GlobalId)) {
rvalue = get_simple_tag(name, *static_cast<EbmlMaster *>(m[i]));
if (rvalue != "")
return rvalue;
}
return "";
}
static int64_t
get_tag_tuid(KaxTag &tag) {
KaxTagTargets *targets;
KaxTagTrackUID *tuid;
targets = FINDFIRST(&tag, KaxTagTargets);
if (targets == NULL)
return -1;
tuid = FINDFIRST(targets, KaxTagTrackUID);
if (tuid == NULL)
return -1;
return uint64(*static_cast<EbmlUInteger *>(tuid));
}
static int64_t
get_tag_cuid(KaxTag &tag) {
KaxTagTargets *targets;
KaxTagChapterUID *cuid;
targets = FINDFIRST(&tag, KaxTagTargets);
if (targets == NULL)
return -1;
cuid = FINDFIRST(targets, KaxTagChapterUID);
if (cuid == NULL)
return -1;
return uint64(*static_cast<EbmlUInteger *>(cuid));
}
static KaxTag *
find_tag_for_track(int idx,
int64_t tuid,
@ -148,7 +80,7 @@ find_tag_for_track(int idx,
continue;
tag_tuid = get_tag_tuid(*static_cast<KaxTag *>(m[i]));
if (((tuid == -1) || (tag_tuid == -1) || (tuid == tag_tuid)) &&
((get_simple_tag("PART_NUMBER",
((get_simple_tag_value("PART_NUMBER",
*static_cast<EbmlMaster *>(m[i])) == sidx) ||
(idx == -1)))
return static_cast<KaxTag *>(m[i]);
@ -167,7 +99,7 @@ get_global_tag(const char *name,
if (tag == NULL)
return "";
return get_simple_tag(name, *tag);
return get_simple_tag_value(name, *tag);
}
static int64_t
@ -185,28 +117,6 @@ get_chapter_index(int idx,
return -1;
}
static string
get_simple_tag_name(KaxTagSimple &tag) {
KaxTagName *tname;
tname = FINDFIRST(&tag, KaxTagName);
if (tname == NULL)
return "";
return UTFstring_to_cstrutf8(UTFstring(*static_cast<EbmlUnicodeString *>
(tname)));
}
static string
get_simple_tag_value(KaxTagSimple &tag) {
KaxTagString *tstring;
tstring = FINDFIRST(&tag, KaxTagString);
if (tstring == NULL)
return "";
return UTFstring_to_cstrutf8(UTFstring(*static_cast<EbmlUnicodeString *>
(tstring)));
}
#define print_if_global(name, format) \
_print_if_global(out, name, format, chapters.ListSize(), tuid, tags)
static void
@ -234,7 +144,7 @@ _print_if_available(mm_io_c &out,
KaxTag &tag) {
string value;
value = get_simple_tag(name, tag);
value = get_simple_tag_value(name, tag);
if ((value != "") &&
(value != get_global_tag(name, tuid, tags)))
out.printf(format, value.c_str());

View File

@ -88,6 +88,7 @@
#include "r_vobsub.h"
#include "r_wav.h"
#include "tagparser.h"
#include "tag_common.h"
#include "xml_element_mapping.h"
using namespace libmatroska;
@ -685,45 +686,6 @@ parse_and_add_tags(const char *file_name) {
delete tags;
}
/** \brief Convert older tags to current specs
*/
void
convert_old_tags(KaxTag *tag) {
KaxTagTargets *targets;
KaxTagSimple *simple;
KaxTagName *kname;
KaxTagString *kvalue;
string name, value;
int i;
targets = &GetChild<KaxTagTargets>(*tag);
i = 0;
while (i < tag->ListSize()) {
simple = dynamic_cast<KaxTagSimple *>((*tag)[i]);
if (simple == NULL) {
i++;
continue;
}
kname = FINDFIRST(simple, KaxTagName);
kvalue = FINDFIRST(simple, KaxTagString);
if ((kname != NULL) && (kvalue != NULL)) {
name = UTFstring_to_cstrutf8((const UTFstring &)(*kname));
value = UTFstring_to_cstrutf8((const UTFstring &)(*kvalue));
if (name == "CATALOG")
*static_cast<EbmlUnicodeString *>(kname) =
cstrutf8_to_UTFstring("CATALOG_NUMBER");
else if (name == "DATE")
*static_cast<EbmlUnicodeString *>(kname) =
cstrutf8_to_UTFstring("DATE_RELEASED");
else if (name == "LEVEL_TYPE") {
// TO BE DONE!
}
}
}
}
/** \brief Add some tags to the list of all tags
*/
void
@ -731,7 +693,6 @@ add_tags(KaxTag *tags) {
if (!accept_tags)
return;
convert_old_tags(tags);
if (tags->ListSize() == 0)
return;

View File

@ -29,6 +29,7 @@
#include "mkvmerge.h"
#include "pr_generic.h"
#include "tagparser.h"
#include "tag_common.h"
using namespace std;
@ -268,6 +269,7 @@ generic_packetizer_c::set_tag_track_uid() {
if (ti->tags == NULL)
return;
convert_old_tags(*ti->tags);
for (is = 0; is < ti->tags->ListSize(); is++) {
tag = (KaxTag *)(*ti->tags)[is];