mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 09:10:36 +00:00
tag: add some utility functions for language codes and tags
Add some utility functions for language tags and ISO-639 codes. These are useful for both GUIs and elements. The iso-codes package is used for language name translations if available. API: gst_tag_get_language_codes() API: gst_tag_get_language_name() API: gst_tag_get_language_code() API: gst_tag_get_language_code_iso_639_1() API: gst_tag_get_language_code_iso_639_2B() API: gst_tag_get_language_code_iso_639_2T()
This commit is contained in:
parent
e897373a0a
commit
088c7c07a2
11 changed files with 1341 additions and 2 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -42,3 +42,5 @@ Makefile.in
|
||||||
Makefile
|
Makefile
|
||||||
*.gir
|
*.gir
|
||||||
*.typelib
|
*.typelib
|
||||||
|
|
||||||
|
gst-libs/gst/tag/mklangtables
|
||||||
|
|
53
configure.ac
53
configure.ac
|
@ -348,6 +348,56 @@ if test "x$HAVE_SYS_SOCKET_H" != "xyes"; then
|
||||||
AG_GST_DISABLE_PLUGIN(tcp)
|
AG_GST_DISABLE_PLUGIN(tcp)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
dnl iso-codes is optional, used by libgsttag
|
||||||
|
AC_ARG_ENABLE(iso-codes,
|
||||||
|
AC_HELP_STRING([--enable-iso-codes],[use iso-codes if installed]),
|
||||||
|
[case "${enableval}" in
|
||||||
|
yes) enable_iso_codes=yes ;;
|
||||||
|
no) enable_iso_codes=no ;;
|
||||||
|
*) AC_MSG_ERROR(bad value ${enableval} for --enable-iso-codes) ;;
|
||||||
|
esac
|
||||||
|
],
|
||||||
|
[enable_iso_codes=yes]) dnl Default value
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([whether to use iso-codes if they are available])
|
||||||
|
if test "x$enable_iso_codes" = "xyes"; then
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
have_iso_codes=no
|
||||||
|
AC_MSG_CHECKING([whether iso-codes are available on this system])
|
||||||
|
if $PKG_CONFIG iso-codes; then
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
AC_MSG_CHECKING([whether iso-codes has iso-639 domain])
|
||||||
|
if $PKG_CONFIG --variable=domains iso-codes | $GREP -q 639 ; then
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
AC_MSG_CHECKING([for iso-codes prefix])
|
||||||
|
ISO_CODES_PREFIX=`$PKG_CONFIG --variable=prefix iso-codes`
|
||||||
|
if test -d "$ISO_CODES_PREFIX"; then
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
AC_MSG_CHECKING([ISO_CODES_PREFIX])
|
||||||
|
AC_MSG_RESULT([$ISO_CODES_PREFIX])
|
||||||
|
ISO_639_DOMAIN="iso_639"
|
||||||
|
AC_MSG_CHECKING([ISO_639_DOMAIN])
|
||||||
|
AC_MSG_RESULT([$ISO_639_DOMAIN])
|
||||||
|
have_iso_codes=yes
|
||||||
|
AC_DEFINE([HAVE_ISO_CODES], [1], [make use of iso-codes for ISO-639])
|
||||||
|
AC_DEFINE_UNQUOTED([ISO_CODES_PREFIX], ["$ISO_CODES_PREFIX"], [prefix])
|
||||||
|
ISO_CODES_VERSION=`$PKG_CONFIG --modversion iso-codes`
|
||||||
|
AC_DEFINE_UNQUOTED([ISO_CODES_VERSION], ["$ISO_CODES_VERSION"], [ ])
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
fi
|
||||||
|
AM_CONDITIONAL(USE_ISO_CODES, test "x$have_iso_codes" = "xyes")
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([no (disabled via --disable-iso-codes)])
|
||||||
|
AM_CONDITIONAL(USE_ISO_CODES, false)
|
||||||
|
fi
|
||||||
|
|
||||||
dnl *** sys plug-ins ***
|
dnl *** sys plug-ins ***
|
||||||
|
|
||||||
echo
|
echo
|
||||||
|
@ -847,6 +897,7 @@ sed \
|
||||||
-e 's/.* HAVE_CPU_I386$/#define HAVE_CPU_I386 1/' \
|
-e 's/.* HAVE_CPU_I386$/#define HAVE_CPU_I386 1/' \
|
||||||
-e 's/.* HAVE_FGETPOS$/#define HAVE_FGETPOS 1/' \
|
-e 's/.* HAVE_FGETPOS$/#define HAVE_FGETPOS 1/' \
|
||||||
-e 's/.* HAVE_FSETPOS$/#define HAVE_FSETPOS 1/' \
|
-e 's/.* HAVE_FSETPOS$/#define HAVE_FSETPOS 1/' \
|
||||||
|
-e 's/.* HAVE_ISO_CODES$/#undef HAVE_ISO_CODES/' \
|
||||||
-e 's/.* HAVE_LIBXML2$/#define HAVE_LIBXML2 1/' \
|
-e 's/.* HAVE_LIBXML2$/#define HAVE_LIBXML2 1/' \
|
||||||
-e 's/.* HAVE_PROCESS_H$/#define HAVE_PROCESS_H 1/' \
|
-e 's/.* HAVE_PROCESS_H$/#define HAVE_PROCESS_H 1/' \
|
||||||
-e 's/.* HAVE_STDLIB_H$/#define HAVE_STDLIB_H 1/' \
|
-e 's/.* HAVE_STDLIB_H$/#define HAVE_STDLIB_H 1/' \
|
||||||
|
@ -856,6 +907,8 @@ sed \
|
||||||
-e 's/.* HAVE_WIN32$/#define HAVE_WIN32 1/' \
|
-e 's/.* HAVE_WIN32$/#define HAVE_WIN32 1/' \
|
||||||
-e 's/.* HAVE_WINSOCK2_H$/#define HAVE_WINSOCK2_H 1/' \
|
-e 's/.* HAVE_WINSOCK2_H$/#define HAVE_WINSOCK2_H 1/' \
|
||||||
-e 's/.* HOST_CPU$/#define HOST_CPU "i686"/' \
|
-e 's/.* HOST_CPU$/#define HOST_CPU "i686"/' \
|
||||||
|
-e 's/.* ISO_CODES_PREFIX$/#undef ISO_CODES_PREFIX/' \
|
||||||
|
-e 's/.* ISO_CODES_VERSION$/#undef ISO_CODES_VERSION/' \
|
||||||
-e 's/.* LIBDIR$/#ifdef _DEBUG\n# define LIBDIR PREFIX "\\\\debug\\\\lib"\n#else\n# define LIBDIR PREFIX "\\\\lib"\n#endif/' \
|
-e 's/.* LIBDIR$/#ifdef _DEBUG\n# define LIBDIR PREFIX "\\\\debug\\\\lib"\n#else\n# define LIBDIR PREFIX "\\\\lib"\n#endif/' \
|
||||||
-e 's/.* LOCALEDIR$/#define LOCALEDIR PREFIX "\\\\share\\\\locale"/' \
|
-e 's/.* LOCALEDIR$/#define LOCALEDIR PREFIX "\\\\share\\\\locale"/' \
|
||||||
-e "s/.* PACKAGE$/#define PACKAGE \"$PACKAGE\"/" \
|
-e "s/.* PACKAGE$/#define PACKAGE \"$PACKAGE\"/" \
|
||||||
|
|
|
@ -192,6 +192,7 @@
|
||||||
<xi:include href="xml/gsttagvorbis.xml" />
|
<xi:include href="xml/gsttagvorbis.xml" />
|
||||||
<xi:include href="xml/gsttagid3.xml" />
|
<xi:include href="xml/gsttagid3.xml" />
|
||||||
<xi:include href="xml/gsttagdemux.xml" />
|
<xi:include href="xml/gsttagdemux.xml" />
|
||||||
|
<xi:include href="xml/gsttaglanguagecodes.xml" />
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|
||||||
<chapter id="gstreamer-base-utils">
|
<chapter id="gstreamer-base-utils">
|
||||||
|
|
|
@ -1564,6 +1564,18 @@ GstTagDemuxClass
|
||||||
GstTagDemuxResult
|
GstTagDemuxResult
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
|
<SECTION>
|
||||||
|
<FILE>gsttaglanguagecodes</FILE>
|
||||||
|
<INCLUDE>gst/tag/tag.h</INCLUDE>
|
||||||
|
<SUBSECTION>
|
||||||
|
gst_tag_get_language_codes
|
||||||
|
gst_tag_get_language_name
|
||||||
|
gst_tag_get_language_code
|
||||||
|
gst_tag_get_language_code_iso_639_1
|
||||||
|
gst_tag_get_language_code_iso_639_2B
|
||||||
|
gst_tag_get_language_code_iso_639_2T
|
||||||
|
</SECTION>
|
||||||
|
|
||||||
# base utils
|
# base utils
|
||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
|
|
|
@ -6,7 +6,7 @@ libgsttaginclude_HEADERS = \
|
||||||
|
|
||||||
lib_LTLIBRARIES = libgsttag-@GST_MAJORMINOR@.la
|
lib_LTLIBRARIES = libgsttag-@GST_MAJORMINOR@.la
|
||||||
|
|
||||||
libgsttag_@GST_MAJORMINOR@_la_SOURCES = gstvorbistag.c gstid3tag.c tags.c gsttagdemux.c
|
libgsttag_@GST_MAJORMINOR@_la_SOURCES = gstvorbistag.c gstid3tag.c lang.c tags.c gsttagdemux.c
|
||||||
libgsttag_@GST_MAJORMINOR@_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS)
|
libgsttag_@GST_MAJORMINOR@_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS)
|
||||||
libgsttag_@GST_MAJORMINOR@_la_LIBADD = $(GST_BASE_LIBS) $(GST_LIBS)
|
libgsttag_@GST_MAJORMINOR@_la_LIBADD = $(GST_BASE_LIBS) $(GST_LIBS)
|
||||||
libgsttag_@GST_MAJORMINOR@_la_LDFLAGS = $(GST_LIB_LDFLAGS) $(GST_ALL_LDFLAGS) $(GST_LT_LDFLAGS)
|
libgsttag_@GST_MAJORMINOR@_la_LDFLAGS = $(GST_LIB_LDFLAGS) $(GST_ALL_LDFLAGS) $(GST_LT_LDFLAGS)
|
||||||
|
@ -49,3 +49,17 @@ typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib)
|
||||||
|
|
||||||
CLEANFILES = $(BUILT_GIRSOURCES) $(typelibs_DATA)
|
CLEANFILES = $(BUILT_GIRSOURCES) $(typelibs_DATA)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# little program that reads iso_639.xml and outputs tables for us as fallback
|
||||||
|
# for when iso-codes are not available (and so we don't have to read the xml
|
||||||
|
# just to map codes)
|
||||||
|
if USE_ISO_CODES
|
||||||
|
ISO_CODE_PROGS = mklangtables
|
||||||
|
mklangtables_SOURCES = mklangtables.c
|
||||||
|
mklangtables_CFLAGS = $(GST_CFLAGS)
|
||||||
|
mklangtables_LDADD = $(GST_LIBS)
|
||||||
|
else
|
||||||
|
ISO_CODE_PROGS =
|
||||||
|
endif
|
||||||
|
|
||||||
|
noinst_PROGRAMS = $(ISO_CODE_PROGS)
|
||||||
|
|
447
gst-libs/gst/tag/lang-tables.c
Normal file
447
gst-libs/gst/tag/lang-tables.c
Normal file
|
@ -0,0 +1,447 @@
|
||||||
|
/* generated by mklangtables.c iso-codes 3.12 */
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#define ISO_639_FLAG_2T (1 << 0)
|
||||||
|
#define ISO_639_FLAG_2B (1 << 1)
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
|
||||||
|
static const struct
|
||||||
|
{
|
||||||
|
const gchar iso_639_1[3];
|
||||||
|
const gchar iso_639_2[4];
|
||||||
|
guint8 flags;
|
||||||
|
guint16 name_offset;
|
||||||
|
} iso_639_codes[] = {
|
||||||
|
/* Afar */
|
||||||
|
{ "aa", "aar", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 0 },
|
||||||
|
/* Abkhazian */
|
||||||
|
{ "ab", "abk", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 5 },
|
||||||
|
/* Avestan */
|
||||||
|
{ "ae", "ave", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 15 },
|
||||||
|
/* Afrikaans */
|
||||||
|
{ "af", "afr", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 23 },
|
||||||
|
/* Akan */
|
||||||
|
{ "ak", "aka", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 33 },
|
||||||
|
/* Amharic */
|
||||||
|
{ "am", "amh", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 38 },
|
||||||
|
/* Aragonese */
|
||||||
|
{ "an", "arg", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 46 },
|
||||||
|
/* Arabic */
|
||||||
|
{ "ar", "ara", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 56 },
|
||||||
|
/* Assamese */
|
||||||
|
{ "as", "asm", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 63 },
|
||||||
|
/* Avaric */
|
||||||
|
{ "av", "ava", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 72 },
|
||||||
|
/* Aymara */
|
||||||
|
{ "ay", "aym", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 79 },
|
||||||
|
/* Azerbaijani */
|
||||||
|
{ "az", "aze", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 86 },
|
||||||
|
/* Bashkir */
|
||||||
|
{ "ba", "bak", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 98 },
|
||||||
|
/* Belarusian */
|
||||||
|
{ "be", "bel", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 106 },
|
||||||
|
/* Bulgarian */
|
||||||
|
{ "bg", "bul", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 117 },
|
||||||
|
/* Bihari languages */
|
||||||
|
{ "bh", "bih", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 127 },
|
||||||
|
/* Bislama */
|
||||||
|
{ "bi", "bis", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 144 },
|
||||||
|
/* Bambara */
|
||||||
|
{ "bm", "bam", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 152 },
|
||||||
|
/* Bengali */
|
||||||
|
{ "bn", "ben", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 160 },
|
||||||
|
/* Tibetan */
|
||||||
|
{ "bo", "bod", ISO_639_FLAG_2T, 168 },
|
||||||
|
{ "bo", "tib", ISO_639_FLAG_2B, 168 },
|
||||||
|
/* Breton */
|
||||||
|
{ "br", "bre", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 176 },
|
||||||
|
/* Bosnian */
|
||||||
|
{ "bs", "bos", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 183 },
|
||||||
|
/* Catalan; Valencian */
|
||||||
|
{ "ca", "cat", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 191 },
|
||||||
|
/* Chechen */
|
||||||
|
{ "ce", "che", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 210 },
|
||||||
|
/* Chamorro */
|
||||||
|
{ "ch", "cha", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 218 },
|
||||||
|
/* Corsican */
|
||||||
|
{ "co", "cos", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 227 },
|
||||||
|
/* Cree */
|
||||||
|
{ "cr", "cre", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 236 },
|
||||||
|
/* Czech */
|
||||||
|
{ "cs", "ces", ISO_639_FLAG_2T, 241 },
|
||||||
|
{ "cs", "cze", ISO_639_FLAG_2B, 241 },
|
||||||
|
/* Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic */
|
||||||
|
{ "cu", "chu", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 247 },
|
||||||
|
/* Chuvash */
|
||||||
|
{ "cv", "chv", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 328 },
|
||||||
|
/* Welsh */
|
||||||
|
{ "cy", "cym", ISO_639_FLAG_2T, 336 },
|
||||||
|
{ "cy", "wel", ISO_639_FLAG_2B, 336 },
|
||||||
|
/* Danish */
|
||||||
|
{ "da", "dan", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 342 },
|
||||||
|
/* German */
|
||||||
|
{ "de", "deu", ISO_639_FLAG_2T, 349 },
|
||||||
|
{ "de", "ger", ISO_639_FLAG_2B, 349 },
|
||||||
|
/* Divehi; Dhivehi; Maldivian */
|
||||||
|
{ "dv", "div", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 356 },
|
||||||
|
/* Dzongkha */
|
||||||
|
{ "dz", "dzo", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 383 },
|
||||||
|
/* Ewe */
|
||||||
|
{ "ee", "ewe", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 392 },
|
||||||
|
/* Greek, Modern (1453-) */
|
||||||
|
{ "el", "ell", ISO_639_FLAG_2T, 396 },
|
||||||
|
{ "el", "gre", ISO_639_FLAG_2B, 396 },
|
||||||
|
/* English */
|
||||||
|
{ "en", "eng", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 418 },
|
||||||
|
/* Esperanto */
|
||||||
|
{ "eo", "epo", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 426 },
|
||||||
|
/* Spanish; Castilian */
|
||||||
|
{ "es", "spa", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 436 },
|
||||||
|
/* Estonian */
|
||||||
|
{ "et", "est", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 455 },
|
||||||
|
/* Basque */
|
||||||
|
{ "eu", "eus", ISO_639_FLAG_2T, 464 },
|
||||||
|
{ "eu", "baq", ISO_639_FLAG_2B, 464 },
|
||||||
|
/* Persian */
|
||||||
|
{ "fa", "fas", ISO_639_FLAG_2T, 471 },
|
||||||
|
{ "fa", "per", ISO_639_FLAG_2B, 471 },
|
||||||
|
/* Fulah */
|
||||||
|
{ "ff", "ful", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 479 },
|
||||||
|
/* Finnish */
|
||||||
|
{ "fi", "fin", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 485 },
|
||||||
|
/* Fijian */
|
||||||
|
{ "fj", "fij", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 493 },
|
||||||
|
/* Faroese */
|
||||||
|
{ "fo", "fao", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 500 },
|
||||||
|
/* French */
|
||||||
|
{ "fr", "fra", ISO_639_FLAG_2T, 508 },
|
||||||
|
{ "fr", "fre", ISO_639_FLAG_2B, 508 },
|
||||||
|
/* Western Frisian */
|
||||||
|
{ "fy", "fry", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 515 },
|
||||||
|
/* Irish */
|
||||||
|
{ "ga", "gle", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 531 },
|
||||||
|
/* Gaelic; Scottish Gaelic */
|
||||||
|
{ "gd", "gla", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 537 },
|
||||||
|
/* Galician */
|
||||||
|
{ "gl", "glg", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 561 },
|
||||||
|
/* Guarani */
|
||||||
|
{ "gn", "grn", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 570 },
|
||||||
|
/* Gujarati */
|
||||||
|
{ "gu", "guj", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 578 },
|
||||||
|
/* Manx */
|
||||||
|
{ "gv", "glv", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 587 },
|
||||||
|
/* Hausa */
|
||||||
|
{ "ha", "hau", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 592 },
|
||||||
|
/* Hebrew */
|
||||||
|
{ "he", "heb", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 598 },
|
||||||
|
/* Hindi */
|
||||||
|
{ "hi", "hin", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 605 },
|
||||||
|
/* Hiri Motu */
|
||||||
|
{ "ho", "hmo", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 611 },
|
||||||
|
/* Croatian */
|
||||||
|
{ "hr", "hrv", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 621 },
|
||||||
|
/* Haitian; Haitian Creole */
|
||||||
|
{ "ht", "hat", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 630 },
|
||||||
|
/* Hungarian */
|
||||||
|
{ "hu", "hun", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 654 },
|
||||||
|
/* Armenian */
|
||||||
|
{ "hy", "hye", ISO_639_FLAG_2T, 664 },
|
||||||
|
{ "hy", "arm", ISO_639_FLAG_2B, 664 },
|
||||||
|
/* Herero */
|
||||||
|
{ "hz", "her", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 673 },
|
||||||
|
/* Interlingua (International Auxiliary Language Association) */
|
||||||
|
{ "ia", "ina", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 680 },
|
||||||
|
/* Indonesian */
|
||||||
|
{ "id", "ind", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 739 },
|
||||||
|
/* Interlingue; Occidental */
|
||||||
|
{ "ie", "ile", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 750 },
|
||||||
|
/* Igbo */
|
||||||
|
{ "ig", "ibo", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 774 },
|
||||||
|
/* Sichuan Yi; Nuosu */
|
||||||
|
{ "ii", "iii", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 779 },
|
||||||
|
/* Inupiaq */
|
||||||
|
{ "ik", "ipk", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 797 },
|
||||||
|
/* Ido */
|
||||||
|
{ "io", "ido", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 805 },
|
||||||
|
/* Icelandic */
|
||||||
|
{ "is", "isl", ISO_639_FLAG_2T, 809 },
|
||||||
|
{ "is", "ice", ISO_639_FLAG_2B, 809 },
|
||||||
|
/* Italian */
|
||||||
|
{ "it", "ita", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 819 },
|
||||||
|
/* Inuktitut */
|
||||||
|
{ "iu", "iku", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 827 },
|
||||||
|
/* Japanese */
|
||||||
|
{ "ja", "jpn", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 837 },
|
||||||
|
/* Javanese */
|
||||||
|
{ "jv", "jav", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 846 },
|
||||||
|
/* Georgian */
|
||||||
|
{ "ka", "kat", ISO_639_FLAG_2T, 855 },
|
||||||
|
{ "ka", "geo", ISO_639_FLAG_2B, 855 },
|
||||||
|
/* Kongo */
|
||||||
|
{ "kg", "kon", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 864 },
|
||||||
|
/* Kikuyu; Gikuyu */
|
||||||
|
{ "ki", "kik", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 870 },
|
||||||
|
/* Kuanyama; Kwanyama */
|
||||||
|
{ "kj", "kua", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 885 },
|
||||||
|
/* Kazakh */
|
||||||
|
{ "kk", "kaz", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 904 },
|
||||||
|
/* Kalaallisut; Greenlandic */
|
||||||
|
{ "kl", "kal", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 911 },
|
||||||
|
/* Central Khmer */
|
||||||
|
{ "km", "khm", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 936 },
|
||||||
|
/* Kannada */
|
||||||
|
{ "kn", "kan", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 950 },
|
||||||
|
/* Korean */
|
||||||
|
{ "ko", "kor", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 958 },
|
||||||
|
/* Kanuri */
|
||||||
|
{ "kr", "kau", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 965 },
|
||||||
|
/* Kashmiri */
|
||||||
|
{ "ks", "kas", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 972 },
|
||||||
|
/* Kurdish */
|
||||||
|
{ "ku", "kur", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 981 },
|
||||||
|
/* Komi */
|
||||||
|
{ "kv", "kom", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 989 },
|
||||||
|
/* Cornish */
|
||||||
|
{ "kw", "cor", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 994 },
|
||||||
|
/* Kirghiz; Kyrgyz */
|
||||||
|
{ "ky", "kir", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1002 },
|
||||||
|
/* Latin */
|
||||||
|
{ "la", "lat", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1018 },
|
||||||
|
/* Luxembourgish; Letzeburgesch */
|
||||||
|
{ "lb", "ltz", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1024 },
|
||||||
|
/* Ganda */
|
||||||
|
{ "lg", "lug", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1053 },
|
||||||
|
/* Limburgan; Limburger; Limburgish */
|
||||||
|
{ "li", "lim", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1059 },
|
||||||
|
/* Lingala */
|
||||||
|
{ "ln", "lin", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1092 },
|
||||||
|
/* Lao */
|
||||||
|
{ "lo", "lao", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1100 },
|
||||||
|
/* Lithuanian */
|
||||||
|
{ "lt", "lit", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1104 },
|
||||||
|
/* Luba-Katanga */
|
||||||
|
{ "lu", "lub", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1115 },
|
||||||
|
/* Latvian */
|
||||||
|
{ "lv", "lav", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1128 },
|
||||||
|
/* Malagasy */
|
||||||
|
{ "mg", "mlg", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1136 },
|
||||||
|
/* Marshallese */
|
||||||
|
{ "mh", "mah", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1145 },
|
||||||
|
/* Maori */
|
||||||
|
{ "mi", "mri", ISO_639_FLAG_2T, 1157 },
|
||||||
|
{ "mi", "mao", ISO_639_FLAG_2B, 1157 },
|
||||||
|
/* Macedonian */
|
||||||
|
{ "mk", "mkd", ISO_639_FLAG_2T, 1163 },
|
||||||
|
{ "mk", "mac", ISO_639_FLAG_2B, 1163 },
|
||||||
|
/* Malayalam */
|
||||||
|
{ "ml", "mal", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1174 },
|
||||||
|
/* Mongolian */
|
||||||
|
{ "mn", "mon", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1184 },
|
||||||
|
/* Moldavian; Moldovan */
|
||||||
|
{ "mo", "mol", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1194 },
|
||||||
|
/* Marathi */
|
||||||
|
{ "mr", "mar", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1214 },
|
||||||
|
/* Malay */
|
||||||
|
{ "ms", "msa", ISO_639_FLAG_2T, 1222 },
|
||||||
|
{ "ms", "may", ISO_639_FLAG_2B, 1222 },
|
||||||
|
/* Maltese */
|
||||||
|
{ "mt", "mlt", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1228 },
|
||||||
|
/* Burmese */
|
||||||
|
{ "my", "mya", ISO_639_FLAG_2T, 1236 },
|
||||||
|
{ "my", "bur", ISO_639_FLAG_2B, 1236 },
|
||||||
|
/* Nauru */
|
||||||
|
{ "na", "nau", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1244 },
|
||||||
|
/* Bokm?l, Norwegian; Norwegian Bokm?l */
|
||||||
|
{ "nb", "nob", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1250 },
|
||||||
|
/* Ndebele, North; North Ndebele */
|
||||||
|
{ "nd", "nde", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1288 },
|
||||||
|
/* Nepali */
|
||||||
|
{ "ne", "nep", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1318 },
|
||||||
|
/* Ndonga */
|
||||||
|
{ "ng", "ndo", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1325 },
|
||||||
|
/* Dutch; Flemish */
|
||||||
|
{ "nl", "nld", ISO_639_FLAG_2T, 1332 },
|
||||||
|
{ "nl", "dut", ISO_639_FLAG_2B, 1332 },
|
||||||
|
/* Norwegian Nynorsk; Nynorsk, Norwegian */
|
||||||
|
{ "nn", "nno", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1347 },
|
||||||
|
/* Norwegian */
|
||||||
|
{ "no", "nor", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1385 },
|
||||||
|
/* Ndebele, South; South Ndebele */
|
||||||
|
{ "nr", "nbl", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1395 },
|
||||||
|
/* Navajo; Navaho */
|
||||||
|
{ "nv", "nav", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1425 },
|
||||||
|
/* Chichewa; Chewa; Nyanja */
|
||||||
|
{ "ny", "nya", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1440 },
|
||||||
|
/* Occitan (post 1500) */
|
||||||
|
{ "oc", "oci", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1464 },
|
||||||
|
/* Ojibwa */
|
||||||
|
{ "oj", "oji", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1484 },
|
||||||
|
/* Oromo */
|
||||||
|
{ "om", "orm", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1491 },
|
||||||
|
/* Oriya */
|
||||||
|
{ "or", "ori", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1497 },
|
||||||
|
/* Ossetian; Ossetic */
|
||||||
|
{ "os", "oss", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1503 },
|
||||||
|
/* Panjabi; Punjabi */
|
||||||
|
{ "pa", "pan", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1521 },
|
||||||
|
/* Pali */
|
||||||
|
{ "pi", "pli", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1538 },
|
||||||
|
/* Polish */
|
||||||
|
{ "pl", "pol", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1543 },
|
||||||
|
/* Pushto; Pashto */
|
||||||
|
{ "ps", "pus", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1550 },
|
||||||
|
/* Portuguese */
|
||||||
|
{ "pt", "por", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1565 },
|
||||||
|
/* Quechua */
|
||||||
|
{ "qu", "que", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1576 },
|
||||||
|
/* Romansh */
|
||||||
|
{ "rm", "roh", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1584 },
|
||||||
|
/* Rundi */
|
||||||
|
{ "rn", "run", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1592 },
|
||||||
|
/* Romanian */
|
||||||
|
{ "ro", "ron", ISO_639_FLAG_2T, 1598 },
|
||||||
|
{ "ro", "rum", ISO_639_FLAG_2B, 1598 },
|
||||||
|
/* Russian */
|
||||||
|
{ "ru", "rus", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1607 },
|
||||||
|
/* Kinyarwanda */
|
||||||
|
{ "rw", "kin", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1615 },
|
||||||
|
/* Sanskrit */
|
||||||
|
{ "sa", "san", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1627 },
|
||||||
|
/* Sardinian */
|
||||||
|
{ "sc", "srd", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1636 },
|
||||||
|
/* Sindhi */
|
||||||
|
{ "sd", "snd", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1646 },
|
||||||
|
/* Northern Sami */
|
||||||
|
{ "se", "sme", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1653 },
|
||||||
|
/* Sango */
|
||||||
|
{ "sg", "sag", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1667 },
|
||||||
|
/* Sinhala; Sinhalese */
|
||||||
|
{ "si", "sin", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1673 },
|
||||||
|
/* Slovak */
|
||||||
|
{ "sk", "slk", ISO_639_FLAG_2T, 1692 },
|
||||||
|
{ "sk", "slo", ISO_639_FLAG_2B, 1692 },
|
||||||
|
/* Slovenian */
|
||||||
|
{ "sl", "slv", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1699 },
|
||||||
|
/* Samoan */
|
||||||
|
{ "sm", "smo", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1709 },
|
||||||
|
/* Shona */
|
||||||
|
{ "sn", "sna", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1716 },
|
||||||
|
/* Somali */
|
||||||
|
{ "so", "som", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1722 },
|
||||||
|
/* Albanian */
|
||||||
|
{ "sq", "sqi", ISO_639_FLAG_2T, 1729 },
|
||||||
|
{ "sq", "alb", ISO_639_FLAG_2B, 1729 },
|
||||||
|
/* Serbian */
|
||||||
|
{ "sr", "srp", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1738 },
|
||||||
|
/* Swati */
|
||||||
|
{ "ss", "ssw", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1746 },
|
||||||
|
/* Sotho, Southern */
|
||||||
|
{ "st", "sot", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1752 },
|
||||||
|
/* Sundanese */
|
||||||
|
{ "su", "sun", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1768 },
|
||||||
|
/* Swedish */
|
||||||
|
{ "sv", "swe", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1778 },
|
||||||
|
/* Swahili */
|
||||||
|
{ "sw", "swa", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1786 },
|
||||||
|
/* Tamil */
|
||||||
|
{ "ta", "tam", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1794 },
|
||||||
|
/* Telugu */
|
||||||
|
{ "te", "tel", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1800 },
|
||||||
|
/* Tajik */
|
||||||
|
{ "tg", "tgk", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1807 },
|
||||||
|
/* Thai */
|
||||||
|
{ "th", "tha", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1813 },
|
||||||
|
/* Tigrinya */
|
||||||
|
{ "ti", "tir", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1818 },
|
||||||
|
/* Turkmen */
|
||||||
|
{ "tk", "tuk", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1827 },
|
||||||
|
/* Tagalog */
|
||||||
|
{ "tl", "tgl", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1835 },
|
||||||
|
/* Tswana */
|
||||||
|
{ "tn", "tsn", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1843 },
|
||||||
|
/* Tonga (Tonga Islands) */
|
||||||
|
{ "to", "ton", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1850 },
|
||||||
|
/* Turkish */
|
||||||
|
{ "tr", "tur", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1872 },
|
||||||
|
/* Tsonga */
|
||||||
|
{ "ts", "tso", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1880 },
|
||||||
|
/* Tatar */
|
||||||
|
{ "tt", "tat", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1887 },
|
||||||
|
/* Twi */
|
||||||
|
{ "tw", "twi", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1893 },
|
||||||
|
/* Tahitian */
|
||||||
|
{ "ty", "tah", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1897 },
|
||||||
|
/* Uighur; Uyghur */
|
||||||
|
{ "ug", "uig", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1906 },
|
||||||
|
/* Ukrainian */
|
||||||
|
{ "uk", "ukr", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1921 },
|
||||||
|
/* Urdu */
|
||||||
|
{ "ur", "urd", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1931 },
|
||||||
|
/* Uzbek */
|
||||||
|
{ "uz", "uzb", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1936 },
|
||||||
|
/* Venda */
|
||||||
|
{ "ve", "ven", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1942 },
|
||||||
|
/* Vietnamese */
|
||||||
|
{ "vi", "vie", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1948 },
|
||||||
|
/* Volap?k */
|
||||||
|
{ "vo", "vol", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1959 },
|
||||||
|
/* Walloon */
|
||||||
|
{ "wa", "wln", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1968 },
|
||||||
|
/* Wolof */
|
||||||
|
{ "wo", "wol", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1976 },
|
||||||
|
/* Xhosa */
|
||||||
|
{ "xh", "xho", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1982 },
|
||||||
|
/* Yiddish */
|
||||||
|
{ "yi", "yid", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1988 },
|
||||||
|
/* Yoruba */
|
||||||
|
{ "yo", "yor", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 1996 },
|
||||||
|
/* Zhuang; Chuang */
|
||||||
|
{ "za", "zha", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 2003 },
|
||||||
|
/* Chinese */
|
||||||
|
{ "zh", "zho", ISO_639_FLAG_2T, 2018 },
|
||||||
|
{ "zh", "chi", ISO_639_FLAG_2B, 2018 },
|
||||||
|
/* Zulu */
|
||||||
|
{ "zu", "zul", ISO_639_FLAG_2T | ISO_639_FLAG_2B, 2026 },
|
||||||
|
};
|
||||||
|
|
||||||
|
const gchar iso_639_names[] =
|
||||||
|
"Afar\000Abkhazian\000Avestan\000Afrikaans\000Akan\000Amharic\000Aragonese"
|
||||||
|
"\000Arabic\000Assamese\000Avaric\000Aymara\000Azerbaijani\000Bashkir\000B"
|
||||||
|
"elarusian\000Bulgarian\000Bihari languages\000Bislama\000Bambara\000Benga"
|
||||||
|
"li\000Tibetan\000Breton\000Bosnian\000Catalan; Valencian\000Chechen\000Ch"
|
||||||
|
"amorro\000Corsican\000Cree\000Czech\000Church Slavic; Old Slavonic; Churc"
|
||||||
|
"h Slavonic; Old Bulgarian; Old Church Slavonic\000Chuvash\000Welsh\000Dan"
|
||||||
|
"ish\000German\000Divehi; Dhivehi; Maldivian\000Dzongkha\000Ewe\000Greek, "
|
||||||
|
"Modern (1453-)\000English\000Esperanto\000Spanish; Castilian\000Estonian"
|
||||||
|
"\000Basque\000Persian\000Fulah\000Finnish\000Fijian\000Faroese\000French"
|
||||||
|
"\000Western Frisian\000Irish\000Gaelic; Scottish Gaelic\000Galician\000Gu"
|
||||||
|
"arani\000Gujarati\000Manx\000Hausa\000Hebrew\000Hindi\000Hiri Motu\000Cro"
|
||||||
|
"atian\000Haitian; Haitian Creole\000Hungarian\000Armenian\000Herero\000In"
|
||||||
|
"terlingua (International Auxiliary Language Association)\000Indonesian"
|
||||||
|
"\000Interlingue; Occidental\000Igbo\000Sichuan Yi; Nuosu\000Inupiaq\000Id"
|
||||||
|
"o\000Icelandic\000Italian\000Inuktitut\000Japanese\000Javanese\000Georgia"
|
||||||
|
"n\000Kongo\000Kikuyu; Gikuyu\000Kuanyama; Kwanyama\000Kazakh\000Kalaallis"
|
||||||
|
"ut; Greenlandic\000Central Khmer\000Kannada\000Korean\000Kanuri\000Kashmi"
|
||||||
|
"ri\000Kurdish\000Komi\000Cornish\000Kirghiz; Kyrgyz\000Latin\000Luxembour"
|
||||||
|
"gish; Letzeburgesch\000Ganda\000Limburgan; Limburger; Limburgish\000Linga"
|
||||||
|
"la\000Lao\000Lithuanian\000Luba-Katanga\000Latvian\000Malagasy\000Marshal"
|
||||||
|
"lese\000Maori\000Macedonian\000Malayalam\000Mongolian\000Moldavian; Moldo"
|
||||||
|
"van\000Marathi\000Malay\000Maltese\000Burmese\000Nauru\000Bokm\303\245l, "
|
||||||
|
"Norwegian; Norwegian Bokm\303\245l\000Ndebele, North; North Ndebele\000Ne"
|
||||||
|
"pali\000Ndonga\000Dutch; Flemish\000Norwegian Nynorsk; Nynorsk, Norwegian"
|
||||||
|
"\000Norwegian\000Ndebele, South; South Ndebele\000Navajo; Navaho\000Chich"
|
||||||
|
"ewa; Chewa; Nyanja\000Occitan (post 1500)\000Ojibwa\000Oromo\000Oriya\000"
|
||||||
|
"Ossetian; Ossetic\000Panjabi; Punjabi\000Pali\000Polish\000Pushto; Pashto"
|
||||||
|
"\000Portuguese\000Quechua\000Romansh\000Rundi\000Romanian\000Russian\000K"
|
||||||
|
"inyarwanda\000Sanskrit\000Sardinian\000Sindhi\000Northern Sami\000Sango"
|
||||||
|
"\000Sinhala; Sinhalese\000Slovak\000Slovenian\000Samoan\000Shona\000Somal"
|
||||||
|
"i\000Albanian\000Serbian\000Swati\000Sotho, Southern\000Sundanese\000Swed"
|
||||||
|
"ish\000Swahili\000Tamil\000Telugu\000Tajik\000Thai\000Tigrinya\000Turkmen"
|
||||||
|
"\000Tagalog\000Tswana\000Tonga (Tonga Islands)\000Turkish\000Tsonga\000Ta"
|
||||||
|
"tar\000Twi\000Tahitian\000Uighur; Uyghur\000Ukrainian\000Urdu\000Uzbek"
|
||||||
|
"\000Venda\000Vietnamese\000Volap\303\274k\000Walloon\000Wolof\000Xhosa"
|
||||||
|
"\000Yiddish\000Yoruba\000Zhuang; Chuang\000Chinese\000Zulu";
|
||||||
|
|
||||||
|
/* *INDENT-ON* */
|
491
gst-libs/gst/tag/lang.c
Normal file
491
gst-libs/gst/tag/lang.c
Normal file
|
@ -0,0 +1,491 @@
|
||||||
|
/* GStreamer language codes and names utility functions
|
||||||
|
* Copyright (C) 2009 Tim-Philipp Müller <tim centricular net>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION:gsttaglanguagecodes
|
||||||
|
* @short_description: mappings for ISO-639 language codes and names
|
||||||
|
* @see_also: #GstTagList
|
||||||
|
*
|
||||||
|
* <refsect2>
|
||||||
|
* <para>
|
||||||
|
* Provides helper functions to convert between the various ISO-639 language
|
||||||
|
* codes, and to map language codes to language names.
|
||||||
|
* </para>
|
||||||
|
* </refsect2>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* FIXME 0.11: maybe switch to ISO-639-2 everywhere incl. GST_TAG_LANGUAGE? */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef GETTEXT_PACKAGE
|
||||||
|
#define GETTEXT_PACKAGE "iso_639"
|
||||||
|
|
||||||
|
#define ISO_639_XML_PATH ISO_CODES_PREFIX "/share/xml/iso-codes/iso_639.xml"
|
||||||
|
#define ISO_CODES_LOCALEDIR ISO_CODES_PREFIX "/share/locale"
|
||||||
|
|
||||||
|
#include <gst/gst-i18n-plugin.h>
|
||||||
|
#include <gst/gst.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "lang-tables.c"
|
||||||
|
|
||||||
|
#ifndef GST_DISABLE_GST_DEBUG
|
||||||
|
|
||||||
|
#define GST_CAT_DEFAULT ensure_debug_category()
|
||||||
|
|
||||||
|
static GstDebugCategory *
|
||||||
|
ensure_debug_category (void)
|
||||||
|
{
|
||||||
|
static gsize cat_gonce = 0;
|
||||||
|
|
||||||
|
if (g_once_init_enter (&cat_gonce)) {
|
||||||
|
gsize cat_done;
|
||||||
|
|
||||||
|
cat_done = (gsize) _gst_debug_category_new ("tag-langcodes", 0,
|
||||||
|
"GstTag language codes and names");
|
||||||
|
|
||||||
|
g_once_init_leave (&cat_gonce, cat_done);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (GstDebugCategory *) cat_gonce;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define ensure_debug_category() /* NOOP */
|
||||||
|
|
||||||
|
#endif /* GST_DISABLE_GST_DEBUG */
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* Loading and initing */
|
||||||
|
|
||||||
|
#if defined(HAVE_ISO_CODES)
|
||||||
|
static const gchar *
|
||||||
|
get_val (const gchar ** names, const gchar ** vals, const gchar * name)
|
||||||
|
{
|
||||||
|
while (names != NULL && *names != NULL) {
|
||||||
|
if (strcmp (*names, name) == 0)
|
||||||
|
return *vals;
|
||||||
|
++names;
|
||||||
|
++vals;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
parse_start_element (GMarkupParseContext * ctx, const gchar * element_name,
|
||||||
|
const gchar ** attr_names, const gchar ** attr_vals,
|
||||||
|
gpointer user_data, GError ** error)
|
||||||
|
{
|
||||||
|
GHashTable *ht = (GHashTable *) user_data;
|
||||||
|
const gchar *c1, *c2t, *c2b, *name, *tname;
|
||||||
|
|
||||||
|
if (strcmp (element_name, "iso_639_entry") != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
c1 = get_val (attr_names, attr_vals, "iso_639_1_code");
|
||||||
|
|
||||||
|
/* only interested in languages with an ISO 639-1 code for now */
|
||||||
|
if (c1 == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
c2t = get_val (attr_names, attr_vals, "iso_639_2T_code");
|
||||||
|
c2b = get_val (attr_names, attr_vals, "iso_639_2B_code");
|
||||||
|
name = get_val (attr_names, attr_vals, "name");
|
||||||
|
|
||||||
|
if (c2t == NULL || c2b == NULL || name == NULL) {
|
||||||
|
GST_WARNING ("broken iso_639.xml entry: c2t=%p, c2b=%p, name=%p", c2t,
|
||||||
|
c2b, name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* translate language name */
|
||||||
|
tname = _(name);
|
||||||
|
|
||||||
|
/* if no translation was found, it will return the input string, which we
|
||||||
|
* we don't want to put into the hash table because it will be freed again */
|
||||||
|
if (G_UNLIKELY (tname == name))
|
||||||
|
tname = g_intern_string (name);
|
||||||
|
|
||||||
|
/* now overwrite default/fallback mappings with names in locale language */
|
||||||
|
g_hash_table_replace (ht, (gpointer) g_intern_string (c1), (gpointer) tname);
|
||||||
|
g_hash_table_replace (ht, (gpointer) g_intern_string (c2b), (gpointer) tname);
|
||||||
|
if (strcmp (c2t, c2b) != 0) {
|
||||||
|
g_hash_table_replace (ht, (gpointer) g_intern_string (c2t),
|
||||||
|
(gpointer) tname);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_LOG ("%s %s %s : %s - %s", c1, c2t, c2b, name, tname);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_tag_load_iso_639_xml (GHashTable * ht)
|
||||||
|
{
|
||||||
|
GMappedFile *f;
|
||||||
|
GError *err = NULL;
|
||||||
|
gchar *xml_data;
|
||||||
|
gsize xml_len;
|
||||||
|
|
||||||
|
#ifdef ENABLE_NLS
|
||||||
|
GST_DEBUG ("binding text domain %s to locale dir %s", GETTEXT_PACKAGE,
|
||||||
|
ISO_CODES_LOCALEDIR);
|
||||||
|
bindtextdomain (GETTEXT_PACKAGE, ISO_CODES_LOCALEDIR);
|
||||||
|
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
f = g_mapped_file_new (ISO_639_XML_PATH, FALSE, NULL);
|
||||||
|
if (f != NULL) {
|
||||||
|
xml_data = (gchar *) g_mapped_file_get_contents (f);
|
||||||
|
xml_len = g_mapped_file_get_length (f);
|
||||||
|
} else {
|
||||||
|
if (!g_file_get_contents (ISO_639_XML_PATH, &xml_data, &xml_len, &err)) {
|
||||||
|
GST_WARNING ("Could not read %s: %s", ISO_639_XML_PATH, err->message);
|
||||||
|
g_error_free (err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_utf8_validate (xml_data, xml_len, NULL)) {
|
||||||
|
GMarkupParser xml_parser = { parse_start_element, NULL, NULL, NULL, NULL };
|
||||||
|
GMarkupParseContext *ctx;
|
||||||
|
|
||||||
|
ctx = g_markup_parse_context_new (&xml_parser, 0, ht, NULL);
|
||||||
|
if (!g_markup_parse_context_parse (ctx, xml_data, xml_len, &err)) {
|
||||||
|
GST_WARNING ("Parsing iso_639.xml failed: %s", err->message);
|
||||||
|
g_error_free (err);
|
||||||
|
}
|
||||||
|
g_markup_parse_context_free (ctx);
|
||||||
|
} else {
|
||||||
|
GST_WARNING ("iso_639.xml file is not valid UTF-8");
|
||||||
|
GST_MEMDUMP ("iso_639.xml file", (guint8 *) xml_data, xml_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ... and clean up */
|
||||||
|
if (f != NULL)
|
||||||
|
g_mapped_file_unref (f);
|
||||||
|
else
|
||||||
|
g_free (xml_data);
|
||||||
|
}
|
||||||
|
#endif /* HAVE_ISO_CODES */
|
||||||
|
|
||||||
|
static GHashTable *
|
||||||
|
gst_tag_get_iso_639_ht (void)
|
||||||
|
{
|
||||||
|
static gsize once_val = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (g_once_init_enter (&once_val)) {
|
||||||
|
GHashTable *ht;
|
||||||
|
gsize done_val;
|
||||||
|
|
||||||
|
GST_MEMDUMP ("iso 639 language names (internal default/fallback)",
|
||||||
|
(guint8 *) iso_639_names, sizeof (iso_639_names));
|
||||||
|
|
||||||
|
/* maps code -> language name; all strings are either interned strings
|
||||||
|
* or const static strings from lang-table.c */
|
||||||
|
ht = g_hash_table_new (g_str_hash, g_str_equal);
|
||||||
|
|
||||||
|
/* set up default/fallback mappings */
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (iso_639_codes); ++i) {
|
||||||
|
GST_LOG ("%3d %s %s %c%c 0x%04x %s", i, iso_639_codes[i].iso_639_1,
|
||||||
|
iso_639_codes[i].iso_639_2,
|
||||||
|
((iso_639_codes[i].flags & ISO_639_FLAG_2B)) ? 'B' : '.',
|
||||||
|
((iso_639_codes[i].flags & ISO_639_FLAG_2T)) ? 'T' : '.',
|
||||||
|
iso_639_codes[i].name_offset,
|
||||||
|
iso_639_names + iso_639_codes[i].name_offset);
|
||||||
|
|
||||||
|
#ifdef HAVE_ISO_CODES
|
||||||
|
/* intern these in order to minimise allocations when interning strings
|
||||||
|
* read from the xml file later */
|
||||||
|
g_intern_static_string (iso_639_codes[i].iso_639_1);
|
||||||
|
g_intern_static_string (iso_639_codes[i].iso_639_2);
|
||||||
|
g_intern_static_string (iso_639_names + iso_639_codes[i].name_offset);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* and add default mapping (these strings are always valid) */
|
||||||
|
g_hash_table_insert (ht, (gpointer) iso_639_codes[i].iso_639_1,
|
||||||
|
(gpointer) (iso_639_names + iso_639_codes[i].name_offset));
|
||||||
|
g_hash_table_insert (ht, (gpointer) iso_639_codes[i].iso_639_2,
|
||||||
|
(gpointer) (iso_639_names + iso_639_codes[i].name_offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_ISO_CODES
|
||||||
|
{
|
||||||
|
GstClockTime ts = gst_util_get_timestamp ();
|
||||||
|
|
||||||
|
gst_tag_load_iso_639_xml (ht);
|
||||||
|
|
||||||
|
ts = gst_util_get_timestamp () - ts;
|
||||||
|
GST_INFO ("iso_639.xml loading took %.2gms", (double) ts / GST_MSECOND);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
GST_INFO ("iso-codes disabled or not available");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
done_val = (gsize) ht;
|
||||||
|
g_once_init_leave (&once_val, done_val);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (GHashTable *) once_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
static int
|
||||||
|
qsort_strcmp_func (const void *p1, const void *p2)
|
||||||
|
{
|
||||||
|
return strcmp (*(char *const *) p1, *(char *const *) p2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_tag_get_language_codes:
|
||||||
|
*
|
||||||
|
* Returns a list of known language codes (in form of two-letter ISO-639-1
|
||||||
|
* codes). This is useful for UIs to build a list of available languages for
|
||||||
|
* tagging purposes (e.g. to tag an audio track appropriately in a video or
|
||||||
|
* audio editor).
|
||||||
|
*
|
||||||
|
* Returns: NULL-terminated string array with two-letter language codes. Free
|
||||||
|
* with g_strfreev() when no longer needed.
|
||||||
|
*
|
||||||
|
* Since: 0.10.26
|
||||||
|
*/
|
||||||
|
gchar **
|
||||||
|
gst_tag_get_language_codes (void)
|
||||||
|
{
|
||||||
|
GHashTableIter iter;
|
||||||
|
GHashTable *ht;
|
||||||
|
gpointer key;
|
||||||
|
gchar **codes;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ensure_debug_category ();
|
||||||
|
|
||||||
|
ht = gst_tag_get_iso_639_ht ();
|
||||||
|
|
||||||
|
/* we have at least two keys for each language (-1 code and -2 code) */
|
||||||
|
codes = g_new (gchar *, (g_hash_table_size (ht) / 2) + 1);
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
g_hash_table_iter_init (&iter, ht);
|
||||||
|
while (g_hash_table_iter_next (&iter, &key, NULL)) {
|
||||||
|
const gchar *lang_code = key;
|
||||||
|
|
||||||
|
if (strlen (lang_code) == 2) {
|
||||||
|
codes[i] = g_strdup (lang_code);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
codes[i] = NULL;
|
||||||
|
|
||||||
|
/* be nice and sort the list */
|
||||||
|
qsort (&codes[0], i, sizeof (gchar *), qsort_strcmp_func);
|
||||||
|
|
||||||
|
return codes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_tag_get_language_name:
|
||||||
|
* @language_code: two or three-letter ISO-639 language code
|
||||||
|
*
|
||||||
|
* Returns the name of the language given an ISO-639 language code, such
|
||||||
|
* as often found in a GST_TAG_LANGUAGE tag. The name will be translated
|
||||||
|
* according to the current locale (if the library was built against the
|
||||||
|
* iso-codes package), otherwise the English name will be returned.
|
||||||
|
*
|
||||||
|
* Language codes are case-sensitive and expected to be lower case.
|
||||||
|
*
|
||||||
|
* Returns: language name in UTF-8 format. The returned string must not be
|
||||||
|
* modified and does not need to freed; it will stay valid until the
|
||||||
|
* application is terminated.
|
||||||
|
*
|
||||||
|
* Since: 0.10.26
|
||||||
|
*/
|
||||||
|
const gchar *
|
||||||
|
gst_tag_get_language_name (const gchar * language_code)
|
||||||
|
{
|
||||||
|
const gchar *lang_name;
|
||||||
|
GHashTable *ht;
|
||||||
|
|
||||||
|
g_return_val_if_fail (language_code != NULL, NULL);
|
||||||
|
|
||||||
|
ensure_debug_category ();
|
||||||
|
|
||||||
|
ht = gst_tag_get_iso_639_ht ();
|
||||||
|
|
||||||
|
lang_name = g_hash_table_lookup (ht, (gpointer) language_code);
|
||||||
|
GST_LOG ("%s -> %s", language_code, GST_STR_NULL (lang_name));
|
||||||
|
|
||||||
|
return lang_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_tag_get_language_code_iso_639_1:
|
||||||
|
* @lang_code: ISO-639 language code (e.g. "deu" or "ger" or "de")
|
||||||
|
*
|
||||||
|
* Returns two-letter ISO-639-1 language code given a three-letter ISO-639-2
|
||||||
|
* language code or two-letter ISO-639-1 language code (both are accepted for
|
||||||
|
* convenience).
|
||||||
|
*
|
||||||
|
* Language codes are case-sensitive and expected to be lower case.
|
||||||
|
*
|
||||||
|
* Returns two-letter ISO-639-1 language code string that maps to @lang_code,
|
||||||
|
* or NULL if no mapping is known. The returned string must not be
|
||||||
|
* modified or freed.
|
||||||
|
*
|
||||||
|
* Since: 0.10.26
|
||||||
|
*/
|
||||||
|
const gchar *
|
||||||
|
gst_tag_get_language_code_iso_639_1 (const gchar * lang_code)
|
||||||
|
{
|
||||||
|
const gchar *c = NULL;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
g_return_val_if_fail (lang_code != NULL, NULL);
|
||||||
|
|
||||||
|
ensure_debug_category ();
|
||||||
|
|
||||||
|
/* FIXME: we are being a bit inconsistent here in the sense that will only
|
||||||
|
* map the language codes from our static table. Theoretically the iso-codes
|
||||||
|
* XML file might have had additional codes that are now in the hash table.
|
||||||
|
* We keep it simple for now and don't waste memory on additional tables. */
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (iso_639_codes); ++i) {
|
||||||
|
/* we check both codes here, so function can be used in a more versatile
|
||||||
|
* way, to convert a language tag to a two-letter language code and/or
|
||||||
|
* verify an existing code */
|
||||||
|
if (strcmp (lang_code, iso_639_codes[i].iso_639_1) == 0 ||
|
||||||
|
strcmp (lang_code, iso_639_codes[i].iso_639_2) == 0) {
|
||||||
|
c = iso_639_codes[i].iso_639_1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_LOG ("%s -> %s", lang_code, GST_STR_NULL (c));
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const gchar *
|
||||||
|
gst_tag_get_language_code_iso_639_2X (const gchar * lang_code, guint8 flags)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* FIXME: we are being a bit inconsistent here in the sense that we will only
|
||||||
|
* map the language codes from our static table. Theoretically the iso-codes
|
||||||
|
* XML file might have had additional codes that are now in the hash table.
|
||||||
|
* We keep it simple for now and don't waste memory on additional tables.
|
||||||
|
* Also, we currently only parse the iso_639.xml file if language names or
|
||||||
|
* a list of all codes is requested, and it'd be nice to keep it like that. */
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (iso_639_codes); ++i) {
|
||||||
|
/* we check both codes here, so function can be used in a more versatile
|
||||||
|
* way, to convert a language tag to a three-letter language code and/or
|
||||||
|
* verify an existing code */
|
||||||
|
if (strcmp (lang_code, iso_639_codes[i].iso_639_1) == 0 ||
|
||||||
|
strcmp (lang_code, iso_639_codes[i].iso_639_2) == 0) {
|
||||||
|
if ((iso_639_codes[i].flags & flags) == flags) {
|
||||||
|
return iso_639_codes[i].iso_639_2;
|
||||||
|
} else if (i > 0 && (iso_639_codes[i - 1].flags & flags) == flags &&
|
||||||
|
iso_639_codes[i].name_offset == iso_639_codes[i - 1].name_offset) {
|
||||||
|
return iso_639_codes[i - 1].iso_639_2;
|
||||||
|
} else if (i < G_N_ELEMENTS (iso_639_codes) &&
|
||||||
|
(iso_639_codes[i + 1].flags & flags) == flags &&
|
||||||
|
iso_639_codes[i].name_offset == iso_639_codes[i + 1].name_offset) {
|
||||||
|
return iso_639_codes[i + 1].iso_639_2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_tag_get_language_code_iso_639_2T:
|
||||||
|
* @lang_code: ISO-639 language code (e.g. "deu" or "ger" or "de")
|
||||||
|
*
|
||||||
|
* Returns three-letter ISO-639-2 "terminological" language code given a
|
||||||
|
* two-letter ISO-639-1 language code or a three-letter ISO-639-2 language
|
||||||
|
* code (both are accepted for convenience).
|
||||||
|
*
|
||||||
|
* The "terminological" code is derived from the local name of the language
|
||||||
|
* (e.g. "deu" for German instead of "ger"). In most scenarios, the
|
||||||
|
* "terminological" codes are prefered over the "bibliographic" ones.
|
||||||
|
*
|
||||||
|
* Language codes are case-sensitive and expected to be lower case.
|
||||||
|
*
|
||||||
|
* Returns three-letter ISO-639-2 language code string that maps to @lang_code,
|
||||||
|
* or NULL if no mapping is known. The returned string must not be
|
||||||
|
* modified or freed.
|
||||||
|
*
|
||||||
|
* Since: 0.10.26
|
||||||
|
*/
|
||||||
|
const gchar *
|
||||||
|
gst_tag_get_language_code_iso_639_2T (const gchar * lang_code)
|
||||||
|
{
|
||||||
|
const gchar *c;
|
||||||
|
|
||||||
|
g_return_val_if_fail (lang_code != NULL, NULL);
|
||||||
|
|
||||||
|
ensure_debug_category ();
|
||||||
|
|
||||||
|
c = gst_tag_get_language_code_iso_639_2X (lang_code, ISO_639_FLAG_2T);
|
||||||
|
|
||||||
|
GST_LOG ("%s -> %s", lang_code, GST_STR_NULL (c));
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_tag_get_language_code_iso_639_2B:
|
||||||
|
* @lang_code: ISO-639 language code (e.g. "deu" or "ger" or "de")
|
||||||
|
*
|
||||||
|
* Returns three-letter ISO-639-2 "bibliographic" language code given a
|
||||||
|
* two-letter ISO-639-1 language code or a three-letter ISO-639-2 language
|
||||||
|
* code (both are accepted for convenience).
|
||||||
|
*
|
||||||
|
* The "bibliographic" code is derived from the English name of the language
|
||||||
|
* (e.g. "ger" for German instead of "de" or "deu"). In most scenarios, the
|
||||||
|
* "terminological" codes are prefered.
|
||||||
|
*
|
||||||
|
* Language codes are case-sensitive and expected to be lower case.
|
||||||
|
*
|
||||||
|
* Returns three-letter ISO-639-2 language code string that maps to @lang_code,
|
||||||
|
* or NULL if no mapping is known. The returned string must not be
|
||||||
|
* modified or freed.
|
||||||
|
*
|
||||||
|
* Since: 0.10.26
|
||||||
|
*/
|
||||||
|
const gchar *
|
||||||
|
gst_tag_get_language_code_iso_639_2B (const gchar * lang_code)
|
||||||
|
{
|
||||||
|
const gchar *c;
|
||||||
|
|
||||||
|
g_return_val_if_fail (lang_code != NULL, NULL);
|
||||||
|
|
||||||
|
ensure_debug_category ();
|
||||||
|
|
||||||
|
c = gst_tag_get_language_code_iso_639_2X (lang_code, ISO_639_FLAG_2B);
|
||||||
|
|
||||||
|
GST_LOG ("%s -> %s", lang_code, GST_STR_NULL (c));
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
239
gst-libs/gst/tag/mklangtables.c
Normal file
239
gst-libs/gst/tag/mklangtables.c
Normal file
|
@ -0,0 +1,239 @@
|
||||||
|
/* GStreamer Language Tag Utility Functions
|
||||||
|
* Copyright (C) 2009 Tim-Philipp Müller <tim centricular net>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* mklangtables.c:
|
||||||
|
* little program that reads iso_639.xml and outputs tables for us as fallback
|
||||||
|
* for when iso-codes are not available or we fail to read the file for some
|
||||||
|
* reason, and so we don't have to parse the xml file just to map codes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define ISO_639_XML_PATH ISO_CODES_PREFIX "/share/xml/iso-codes/iso_639.xml"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
gchar code_1[3]; /* de */
|
||||||
|
gchar code_2t[4]; /* deu */
|
||||||
|
gchar code_2b[4]; /* ger */
|
||||||
|
const gchar *name; /* German */
|
||||||
|
guint name_offset; /* offset into string table */
|
||||||
|
} IsoLang;
|
||||||
|
|
||||||
|
static GArray *languages = NULL;
|
||||||
|
|
||||||
|
static void
|
||||||
|
dump_languages (void)
|
||||||
|
{
|
||||||
|
GString *names;
|
||||||
|
const char *s;
|
||||||
|
int i, num_escaped;
|
||||||
|
|
||||||
|
g_assert (languages != NULL);
|
||||||
|
|
||||||
|
names = g_string_new ("");
|
||||||
|
|
||||||
|
g_print ("/* generated by " __FILE__ " iso-codes " ISO_CODES_VERSION " */\n");
|
||||||
|
g_print ("\n");
|
||||||
|
g_print ("#include <glib.h>\n");
|
||||||
|
g_print ("\n");
|
||||||
|
g_print ("#define ISO_639_FLAG_2T (1 << 0)\n");
|
||||||
|
g_print ("#define ISO_639_FLAG_2B (1 << 1)\n");
|
||||||
|
g_print ("\n");
|
||||||
|
g_print ("/* *INDENT-OFF* */\n");
|
||||||
|
g_print ("\n");
|
||||||
|
g_print ("static const struct\n");
|
||||||
|
g_print ("{\n");
|
||||||
|
g_print (" const gchar iso_639_1[3];\n");
|
||||||
|
g_print (" const gchar iso_639_2[4];\n");
|
||||||
|
g_print (" guint8 flags;\n");
|
||||||
|
g_print (" guint16 name_offset;\n");
|
||||||
|
g_print ("} iso_639_codes[] = {\n");
|
||||||
|
|
||||||
|
for (i = 0, num_escaped = 0; i < languages->len; ++i) {
|
||||||
|
IsoLang *lang = &g_array_index (languages, IsoLang, i);
|
||||||
|
|
||||||
|
/* For now just print those where there's both a ISO-639-1 and -2 code */
|
||||||
|
if (lang->code_1[0] == '\0')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* save current offset */
|
||||||
|
lang->name_offset = names->len;
|
||||||
|
|
||||||
|
/* adjust for fact that \000 is 4 chars now but will take up only 1 later */
|
||||||
|
lang->name_offset -= num_escaped * 3;
|
||||||
|
|
||||||
|
/* append one char at a time, making sure to escape UTF-8 characters */
|
||||||
|
for (s = lang->name; s != NULL && *s != '\0'; ++s) {
|
||||||
|
if (g_ascii_isprint (*s) && *s != '"' && *s != '\\') {
|
||||||
|
g_string_append_c (names, *s);
|
||||||
|
} else {
|
||||||
|
g_string_append_printf (names, "\\%03o", (unsigned char) *s);
|
||||||
|
++num_escaped;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_string_append (names, "\\000");
|
||||||
|
++num_escaped;
|
||||||
|
|
||||||
|
g_print (" /* %s */\n", lang->name);
|
||||||
|
if (strcmp (lang->code_2b, lang->code_2t) == 0) {
|
||||||
|
g_print (" { \"%s\", \"%s\", ISO_639_FLAG_2T | ISO_639_FLAG_2B, %u },\n",
|
||||||
|
lang->code_1, lang->code_2t, lang->name_offset);
|
||||||
|
} else {
|
||||||
|
/* if 639-2T and 639-2B differ, put 639-2T first */
|
||||||
|
g_print (" { \"%s\", \"%s\", ISO_639_FLAG_2T, %u },\n",
|
||||||
|
lang->code_1, lang->code_2t, lang->name_offset);
|
||||||
|
g_print (" { \"%s\", \"%s\", ISO_639_FLAG_2B, %u },\n",
|
||||||
|
lang->code_1, lang->code_2b, lang->name_offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_print ("};\n");
|
||||||
|
g_print ("\n");
|
||||||
|
g_print ("const gchar iso_639_names[] =\n");
|
||||||
|
s = names->str;
|
||||||
|
while (s != NULL && *s != '\0') {
|
||||||
|
gchar line[74], *lastesc;
|
||||||
|
guint left;
|
||||||
|
|
||||||
|
left = strlen (s);
|
||||||
|
g_strlcpy (line, s, MIN (left, sizeof (line)));
|
||||||
|
s += sizeof (line) - 1;
|
||||||
|
/* avoid partial escaped codes at the end of a line */
|
||||||
|
if ((lastesc = strrchr (line, '\\')) && strlen (lastesc) < 4) {
|
||||||
|
s -= strlen (lastesc);
|
||||||
|
*lastesc = '\0';
|
||||||
|
}
|
||||||
|
g_print (" \"%s\"", line);
|
||||||
|
if (left < 74)
|
||||||
|
break;
|
||||||
|
g_print ("\n");
|
||||||
|
}
|
||||||
|
g_print (";\n");
|
||||||
|
g_print ("\n");
|
||||||
|
g_print ("/* *INDENT-ON* */\n");
|
||||||
|
|
||||||
|
g_string_free (names, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
copy_attribute (gchar * dest, guint dest_len, const gchar ** attr_names,
|
||||||
|
const gchar ** attr_vals, const gchar * needle)
|
||||||
|
{
|
||||||
|
while (attr_names != NULL && *attr_names != NULL) {
|
||||||
|
if (strcmp (*attr_names, needle) == 0) {
|
||||||
|
g_strlcpy (dest, *attr_vals, dest_len);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
++attr_names;
|
||||||
|
++attr_vals;
|
||||||
|
}
|
||||||
|
dest[0] = '\0';
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
xml_start_element (GMarkupParseContext * ctx, const gchar * element_name,
|
||||||
|
const gchar ** attr_names, const gchar ** attr_vals,
|
||||||
|
gpointer user_data, GError ** error)
|
||||||
|
{
|
||||||
|
gchar name[256];
|
||||||
|
IsoLang lang;
|
||||||
|
|
||||||
|
if (strcmp (element_name, "iso_639_entry") != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
copy_attribute (lang.code_1, 3, attr_names, attr_vals, "iso_639_1_code");
|
||||||
|
copy_attribute (lang.code_2t, 4, attr_names, attr_vals, "iso_639_2T_code");
|
||||||
|
copy_attribute (lang.code_2b, 4, attr_names, attr_vals, "iso_639_2B_code");
|
||||||
|
|
||||||
|
copy_attribute (name, sizeof (name), attr_names, attr_vals, "name");
|
||||||
|
lang.name = g_intern_string (name);
|
||||||
|
|
||||||
|
g_array_append_val (languages, lang);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
parse_iso_639_xml (const gchar * data, gsize len)
|
||||||
|
{
|
||||||
|
GMarkupParser xml_parser = { xml_start_element, NULL, NULL, NULL, NULL };
|
||||||
|
GMarkupParseContext *ctx;
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
|
g_return_if_fail (g_utf8_validate (data, len, NULL));
|
||||||
|
|
||||||
|
ctx = g_markup_parse_context_new (&xml_parser, 0, NULL, NULL);
|
||||||
|
if (!g_markup_parse_context_parse (ctx, data, len, &err))
|
||||||
|
g_error ("Parsing failed: %s", err->message);
|
||||||
|
|
||||||
|
g_markup_parse_context_free (ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gint
|
||||||
|
languages_sort_func (IsoLang * l1, IsoLang * l2)
|
||||||
|
{
|
||||||
|
if (l1 == l2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (l1->code_1[0] == '\0' && l2->code_1[0] != '\0')
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return strcmp (l1->code_1, l2->code_1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
GMappedFile *f;
|
||||||
|
gchar *xml_data;
|
||||||
|
gsize xml_len;
|
||||||
|
|
||||||
|
f = g_mapped_file_new (ISO_639_XML_PATH, FALSE, NULL);
|
||||||
|
if (f != NULL) {
|
||||||
|
xml_data = (gchar *) g_mapped_file_get_contents (f);
|
||||||
|
xml_len = g_mapped_file_get_length (f);
|
||||||
|
} else {
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
|
if (!g_file_get_contents (ISO_639_XML_PATH, &xml_data, &xml_len, &err))
|
||||||
|
g_error ("Could not read %s: %s", ISO_639_XML_PATH, err->message);
|
||||||
|
}
|
||||||
|
|
||||||
|
languages = g_array_new (FALSE, TRUE, sizeof (IsoLang));
|
||||||
|
|
||||||
|
parse_iso_639_xml (xml_data, xml_len);
|
||||||
|
|
||||||
|
g_array_sort (languages, (GCompareFunc) languages_sort_func);
|
||||||
|
|
||||||
|
dump_languages ();
|
||||||
|
|
||||||
|
g_array_free (languages, TRUE);
|
||||||
|
|
||||||
|
if (f != NULL)
|
||||||
|
g_mapped_file_unref (f);
|
||||||
|
else
|
||||||
|
g_free (xml_data);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -238,6 +238,30 @@ GstBuffer * gst_tag_image_data_to_image_buffer (const guint8 * ima
|
||||||
/* FIXME 0.11: replace with a more general gst_tag_library_init() */
|
/* FIXME 0.11: replace with a more general gst_tag_library_init() */
|
||||||
void gst_tag_register_musicbrainz_tags (void);
|
void gst_tag_register_musicbrainz_tags (void);
|
||||||
|
|
||||||
|
|
||||||
|
/* language tag related functions */
|
||||||
|
|
||||||
|
gchar ** gst_tag_get_language_codes (void);
|
||||||
|
|
||||||
|
const gchar * gst_tag_get_language_name (const gchar * language_code);
|
||||||
|
|
||||||
|
const gchar * gst_tag_get_language_code_iso_639_1 (const gchar * lang_code);
|
||||||
|
|
||||||
|
const gchar * gst_tag_get_language_code_iso_639_2B (const gchar * lang_code);
|
||||||
|
|
||||||
|
const gchar * gst_tag_get_language_code_iso_639_2T (const gchar * lang_code);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_tag_get_language_code:
|
||||||
|
* @lang_code: ISO-639 language code (e.g. "deu" or "ger" or "de")
|
||||||
|
*
|
||||||
|
* Convenience macro wrapping gst_tag_get_language_code_iso_639_1().
|
||||||
|
*
|
||||||
|
* Since: 0.10.26
|
||||||
|
*/
|
||||||
|
#define gst_tag_get_language_code(lang_code) \
|
||||||
|
gst_tag_get_language_code_iso_639_1(lang_code)
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GST_TAG_TAG_H__ */
|
#endif /* __GST_TAG_TAG_H__ */
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
*
|
*
|
||||||
* unit tests for the tag support library
|
* unit tests for the tag support library
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006 Tim-Philipp Müller <tim centricular net>
|
* Copyright (C) 2006-2009 Tim-Philipp Müller <tim centricular net>
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
@ -682,6 +682,56 @@ GST_START_TEST (test_id3v1_utf8_tag)
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
|
GST_START_TEST (test_language_utils)
|
||||||
|
{
|
||||||
|
gchar **lang_codes, **c;
|
||||||
|
|
||||||
|
lang_codes = gst_tag_get_language_codes ();
|
||||||
|
fail_unless (lang_codes != NULL);
|
||||||
|
fail_unless (*lang_codes != NULL);
|
||||||
|
|
||||||
|
for (c = lang_codes; c != NULL && *c != NULL; ++c) {
|
||||||
|
const gchar *lang_name;
|
||||||
|
|
||||||
|
lang_name = gst_tag_get_language_name (*c);
|
||||||
|
GST_DEBUG ("[%s] %s\n", *c, GST_STR_NULL (lang_name));
|
||||||
|
|
||||||
|
fail_unless (lang_name != NULL);
|
||||||
|
fail_unless (g_utf8_validate (lang_name, -1, NULL));
|
||||||
|
}
|
||||||
|
g_strfreev (lang_codes);
|
||||||
|
|
||||||
|
fail_unless (gst_tag_get_language_name ("de") != NULL);
|
||||||
|
fail_unless (gst_tag_get_language_name ("deu") != NULL);
|
||||||
|
fail_unless (gst_tag_get_language_name ("ger") != NULL);
|
||||||
|
fail_unless_equals_string (gst_tag_get_language_name ("deu"),
|
||||||
|
gst_tag_get_language_name ("ger"));
|
||||||
|
fail_unless_equals_string (gst_tag_get_language_name ("de"),
|
||||||
|
gst_tag_get_language_name ("ger"));
|
||||||
|
fail_unless (gst_tag_get_language_name ("de") !=
|
||||||
|
gst_tag_get_language_name ("fr"));
|
||||||
|
|
||||||
|
#define ASSERT_STRINGS_EQUAL fail_unless_equals_string
|
||||||
|
|
||||||
|
ASSERT_STRINGS_EQUAL (gst_tag_get_language_code ("deu"), "de");
|
||||||
|
ASSERT_STRINGS_EQUAL (gst_tag_get_language_code ("de"), "de");
|
||||||
|
ASSERT_STRINGS_EQUAL (gst_tag_get_language_code ("ger"), "de");
|
||||||
|
|
||||||
|
ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_1 ("deu"), "de");
|
||||||
|
ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_1 ("de"), "de");
|
||||||
|
ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_1 ("ger"), "de");
|
||||||
|
|
||||||
|
ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_2T ("de"), "deu");
|
||||||
|
ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_2T ("deu"), "deu");
|
||||||
|
ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_2T ("ger"), "deu");
|
||||||
|
|
||||||
|
ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_2B ("de"), "ger");
|
||||||
|
ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_2B ("deu"), "ger");
|
||||||
|
ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_2B ("ger"), "ger");
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
static Suite *
|
static Suite *
|
||||||
tag_suite (void)
|
tag_suite (void)
|
||||||
{
|
{
|
||||||
|
@ -694,6 +744,7 @@ tag_suite (void)
|
||||||
tcase_add_test (tc_chain, test_vorbis_tags);
|
tcase_add_test (tc_chain, test_vorbis_tags);
|
||||||
tcase_add_test (tc_chain, test_id3_tags);
|
tcase_add_test (tc_chain, test_id3_tags);
|
||||||
tcase_add_test (tc_chain, test_id3v1_utf8_tag);
|
tcase_add_test (tc_chain, test_id3v1_utf8_tag);
|
||||||
|
tcase_add_test (tc_chain, test_language_utils);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,11 @@ EXPORTS
|
||||||
gst_tag_from_id3_tag
|
gst_tag_from_id3_tag
|
||||||
gst_tag_from_id3_user_tag
|
gst_tag_from_id3_user_tag
|
||||||
gst_tag_from_vorbis_tag
|
gst_tag_from_vorbis_tag
|
||||||
|
gst_tag_get_language_code_iso_639_1
|
||||||
|
gst_tag_get_language_code_iso_639_2B
|
||||||
|
gst_tag_get_language_code_iso_639_2T
|
||||||
|
gst_tag_get_language_codes
|
||||||
|
gst_tag_get_language_name
|
||||||
gst_tag_id3_genre_count
|
gst_tag_id3_genre_count
|
||||||
gst_tag_id3_genre_get
|
gst_tag_id3_genre_get
|
||||||
gst_tag_image_data_to_image_buffer
|
gst_tag_image_data_to_image_buffer
|
||||||
|
|
Loading…
Reference in a new issue