summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2020-01-23 15:37:37 +0100
committerCarl Hetherington <cth@carlh.net>2020-01-23 21:39:12 +0100
commit4f85ccdd794682ed04081755d9272d6f006b4c2f (patch)
tree6c8c48be39547d963d205c9db8479200c5125880
parentd8ded66fccb98bd0145afb2f08cf84aad7002a15 (diff)
Support binary STL subtitle files.v2.14.24
-rw-r--r--cscript2
-rw-r--r--src/lib/content_factory.cc2
-rw-r--r--src/lib/string_text_file.cc100
-rw-r--r--src/lib/text_decoder.cc9
-rw-r--r--wscript4
5 files changed, 70 insertions, 47 deletions
diff --git a/cscript b/cscript
index 74da1bc74..e11b8e369 100644
--- a/cscript
+++ b/cscript
@@ -345,7 +345,7 @@ def dependencies(target):
deps = []
deps.append(('libdcp', 'v1.6.14'))
- deps.append(('libsub', 'v1.4.16'))
+ deps.append(('libsub', 'v1.4.17'))
deps.append(('rtaudio-cdist', 'bf0fc23'))
return deps
diff --git a/src/lib/content_factory.cc b/src/lib/content_factory.cc
index f123061b7..0e8b04eda 100644
--- a/src/lib/content_factory.cc
+++ b/src/lib/content_factory.cc
@@ -166,7 +166,7 @@ content_factory (boost::filesystem::path path)
if (valid_image_file (path)) {
single.reset (new ImageContent(path));
- } else if (ext == ".srt" || ext == ".ssa" || ext == ".ass") {
+ } else if (ext == ".srt" || ext == ".ssa" || ext == ".ass" || ext == ".stl") {
single.reset (new StringTextFileContent(path));
} else if (ext == ".xml") {
cxml::Document doc;
diff --git a/src/lib/string_text_file.cc b/src/lib/string_text_file.cc
index c7eadbbb1..c5b297a8b 100644
--- a/src/lib/string_text_file.cc
+++ b/src/lib/string_text_file.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2014-2018 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2014-2020 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
@@ -24,6 +24,7 @@
#include "string_text_file_content.h"
#include <sub/subrip_reader.h>
#include <sub/ssa_reader.h>
+#include <sub/stl_binary_reader.h>
#include <sub/collect.h>
#include <unicode/ucsdet.h>
#include <unicode/ucnv.h>
@@ -41,50 +42,67 @@ using dcp::Data;
StringTextFile::StringTextFile (shared_ptr<const StringTextFileContent> content)
{
- Data in (content->path (0));
-
- UErrorCode status = U_ZERO_ERROR;
- UCharsetDetector* detector = ucsdet_open (&status);
- ucsdet_setText (detector, reinterpret_cast<const char *> (in.data().get()), in.size(), &status);
-
- UCharsetMatch const * match = ucsdet_detect (detector, &status);
- char const * in_charset = ucsdet_getName (match, &status);
-
- UConverter* to_utf16 = ucnv_open (in_charset, &status);
- /* This is a guess; I think we should be able to encode any input in 4 times its input size */
- scoped_array<uint16_t> utf16 (new uint16_t[in.size() * 2]);
- int const utf16_len = ucnv_toUChars (
- to_utf16, reinterpret_cast<UChar*>(utf16.get()), in.size() * 2,
- reinterpret_cast<const char *> (in.data().get()), in.size(),
- &status
- );
-
- UConverter* to_utf8 = ucnv_open ("UTF-8", &status);
- /* Another guess */
- scoped_array<char> utf8 (new char[utf16_len * 2]);
- ucnv_fromUChars (to_utf8, utf8.get(), utf16_len * 2, reinterpret_cast<UChar*>(utf16.get()), utf16_len, &status);
-
- /* Fix OS X line endings */
- size_t utf8_len = strlen (utf8.get ());
- for (size_t i = 0; i < utf8_len; ++i) {
- if (utf8[i] == '\r' && ((i == utf8_len - 1) || utf8[i + 1] != '\n')) {
- utf8[i] = '\n';
- }
- }
-
- ucsdet_close (detector);
- ucnv_close (to_utf16);
- ucnv_close (to_utf8);
+ string ext = content->path(0).extension().string();
+ transform (ext.begin(), ext.end(), ext.begin(), ::tolower);
sub::Reader* reader = 0;
- string ext = content->path(0).extension().string();
- transform (ext.begin(), ext.end(), ext.begin(), ::tolower);
+ if (ext == ".stl") {
+ FILE* f = fopen_boost (content->path(0), "rb");
+ if (!f) {
+ throw OpenFileError (content->path(0), errno, OpenFileError::READ);
+ }
+ try {
+ reader = new sub::STLBinaryReader (f);
+ } catch (...) {
+ fclose (f);
+ throw;
+ }
+ fclose (f);
+
+ } else {
+ /* Text-based file; sort out its character encoding before we try to parse it */
+
+ Data in (content->path (0));
+
+ UErrorCode status = U_ZERO_ERROR;
+ UCharsetDetector* detector = ucsdet_open (&status);
+ ucsdet_setText (detector, reinterpret_cast<const char *> (in.data().get()), in.size(), &status);
+
+ UCharsetMatch const * match = ucsdet_detect (detector, &status);
+ char const * in_charset = ucsdet_getName (match, &status);
+
+ UConverter* to_utf16 = ucnv_open (in_charset, &status);
+ /* This is a guess; I think we should be able to encode any input in 4 times its input size */
+ scoped_array<uint16_t> utf16 (new uint16_t[in.size() * 2]);
+ int const utf16_len = ucnv_toUChars (
+ to_utf16, reinterpret_cast<UChar*>(utf16.get()), in.size() * 2,
+ reinterpret_cast<const char *> (in.data().get()), in.size(),
+ &status
+ );
+
+ UConverter* to_utf8 = ucnv_open ("UTF-8", &status);
+ /* Another guess */
+ scoped_array<char> utf8 (new char[utf16_len * 2]);
+ ucnv_fromUChars (to_utf8, utf8.get(), utf16_len * 2, reinterpret_cast<UChar*>(utf16.get()), utf16_len, &status);
+
+ /* Fix OS X line endings */
+ size_t utf8_len = strlen (utf8.get ());
+ for (size_t i = 0; i < utf8_len; ++i) {
+ if (utf8[i] == '\r' && ((i == utf8_len - 1) || utf8[i + 1] != '\n')) {
+ utf8[i] = '\n';
+ }
+ }
+
+ ucsdet_close (detector);
+ ucnv_close (to_utf16);
+ ucnv_close (to_utf8);
- if (ext == ".srt") {
- reader = new sub::SubripReader (utf8.get());
- } else if (ext == ".ssa" || ext == ".ass") {
- reader = new sub::SSAReader (utf8.get());
+ if (ext == ".srt") {
+ reader = new sub::SubripReader (utf8.get());
+ } else if (ext == ".ssa" || ext == ".ass") {
+ reader = new sub::SSAReader (utf8.get());
+ }
}
if (reader) {
diff --git a/src/lib/text_decoder.cc b/src/lib/text_decoder.cc
index 74fea6ec3..1e13bb3c9 100644
--- a/src/lib/text_decoder.cc
+++ b/src/lib/text_decoder.cc
@@ -147,9 +147,14 @@ TextDecoder::emit_plain_start (ContentTime from, sub::Subtitle const & subtitle)
v_align = dcp::VALIGN_TOP;
} else {
- DCPOMATIC_ASSERT (i.vertical_position.proportional);
DCPOMATIC_ASSERT (i.vertical_position.reference);
- v_position = i.vertical_position.proportional.get();
+ if (i.vertical_position.proportional) {
+ v_position = i.vertical_position.proportional.get();
+ } else {
+ DCPOMATIC_ASSERT (i.vertical_position.line);
+ DCPOMATIC_ASSERT (i.vertical_position.lines);
+ v_position = float(*i.vertical_position.line) / *i.vertical_position.lines;
+ }
if (lowest_proportional) {
/* Adjust line spacing */
diff --git a/wscript b/wscript
index c7d1a729f..ebabf2147 100644
--- a/wscript
+++ b/wscript
@@ -323,11 +323,11 @@ def configure(conf):
# libsub
if conf.options.static_sub:
- conf.check_cfg(package='libsub-1.0', atleast_version='1.4.15', args='--cflags', uselib_store='SUB', mandatory=True)
+ conf.check_cfg(package='libsub-1.0', atleast_version='1.4.17', args='--cflags', uselib_store='SUB', mandatory=True)
conf.env.DEFINES_SUB = [f.replace('\\', '') for f in conf.env.DEFINES_SUB]
conf.env.STLIB_SUB = ['sub-1.0']
else:
- conf.check_cfg(package='libsub-1.0', atleast_version='1.4.15', args='--cflags --libs', uselib_store='SUB', mandatory=True)
+ conf.check_cfg(package='libsub-1.0', atleast_version='1.4.17', args='--cflags --libs', uselib_store='SUB', mandatory=True)
conf.env.DEFINES_SUB = [f.replace('\\', '') for f in conf.env.DEFINES_SUB]
# libxml++