2013-01-04 16:01:50 +01:00
|
|
|
// Copyright (c) 2013, Thomas Goyne <plorkyeran@aegisub.org>
|
2006-01-16 22:02:54 +01:00
|
|
|
//
|
2013-01-04 16:01:50 +01:00
|
|
|
// Permission to use, copy, modify, and distribute this software for any
|
|
|
|
// purpose with or without fee is hereby granted, provided that the above
|
|
|
|
// copyright notice and this permission notice appear in all copies.
|
2006-01-16 22:02:54 +01:00
|
|
|
//
|
2013-01-04 16:01:50 +01:00
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
|
|
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
|
|
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
|
|
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
|
|
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
|
|
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
|
|
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
2006-01-16 22:02:54 +01:00
|
|
|
//
|
2009-07-29 07:43:02 +02:00
|
|
|
// Aegisub Project http://www.aegisub.org/
|
|
|
|
|
|
|
|
/// @file ass_time.cpp
|
|
|
|
/// @brief Class for managing timestamps in subtitles
|
|
|
|
/// @ingroup subs_storage
|
|
|
|
///
|
2006-01-16 22:02:54 +01:00
|
|
|
|
2009-10-09 18:34:38 +02:00
|
|
|
#include "config.h"
|
|
|
|
|
2011-12-22 22:28:41 +01:00
|
|
|
#include "ass_time.h"
|
2009-09-10 15:06:40 +02:00
|
|
|
|
2013-01-04 16:01:50 +01:00
|
|
|
#include "utils.h"
|
2012-03-29 21:04:36 +02:00
|
|
|
|
2013-01-04 16:01:50 +01:00
|
|
|
#include <libaegisub/util.h>
|
2006-01-16 22:02:54 +01:00
|
|
|
|
2013-01-04 16:01:50 +01:00
|
|
|
#include <algorithm>
|
|
|
|
#include <boost/algorithm/string/classification.hpp>
|
|
|
|
#include <boost/algorithm/string/split.hpp>
|
|
|
|
#include <boost/format.hpp>
|
|
|
|
#include <boost/range/adaptor/filtered.hpp>
|
2006-01-16 22:02:54 +01:00
|
|
|
|
2011-12-22 22:28:51 +01:00
|
|
|
AssTime::AssTime(int time) : time(mid(0, time, 10 * 60 * 60 * 1000 - 1)) { }
|
2006-01-16 22:02:54 +01:00
|
|
|
|
2013-01-04 16:01:50 +01:00
|
|
|
AssTime::AssTime(std::string const& text)
|
2012-02-14 01:35:06 +01:00
|
|
|
: time(0)
|
|
|
|
{
|
2013-01-04 16:01:50 +01:00
|
|
|
int after_decimal = -1;
|
|
|
|
int current = 0;
|
2013-10-08 16:19:56 +02:00
|
|
|
for (char c : text | boost::adaptors::filtered(boost::is_any_of(",.0123456789:"))) {
|
2013-01-04 16:01:50 +01:00
|
|
|
if (c == ':') {
|
|
|
|
time = time * 60 + current;
|
|
|
|
current = 0;
|
|
|
|
}
|
2013-10-08 16:19:56 +02:00
|
|
|
else if (c == '.' || c == ',') {
|
2013-01-04 16:01:50 +01:00
|
|
|
time = (time * 60 + current) * 1000;
|
|
|
|
current = 0;
|
|
|
|
after_decimal = 100;
|
|
|
|
}
|
|
|
|
else if (after_decimal < 0) {
|
|
|
|
current *= 10;
|
|
|
|
current += c - '0';
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
time += (c - '0') * after_decimal;
|
|
|
|
after_decimal /= 10;
|
|
|
|
}
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
|
2013-01-04 16:01:50 +01:00
|
|
|
// Never saw a decimal, so convert now to ms
|
|
|
|
if (after_decimal < 0)
|
|
|
|
time = (time * 60 + current) * 1000;
|
2012-03-12 00:04:56 +01:00
|
|
|
|
|
|
|
// Limit to the valid range
|
|
|
|
time = mid(0, time, 10 * 60 * 60 * 1000 - 1);
|
2006-02-21 23:09:15 +01:00
|
|
|
}
|
|
|
|
|
2013-01-04 16:01:50 +01:00
|
|
|
std::string AssTime::GetAssFormated(bool msPrecision) const {
|
|
|
|
std::string ret(10 + msPrecision, ':');
|
|
|
|
ret[0] = '0' + GetTimeHours();
|
|
|
|
ret[2] = '0' + (time % (60 * 60 * 1000)) / (60 * 1000 * 10);
|
|
|
|
ret[3] = '0' + (time % (10 * 60 * 1000)) / (60 * 1000);
|
|
|
|
ret[5] = '0' + (time % (60 * 1000)) / (1000 * 10);
|
|
|
|
ret[6] = '0' + (time % (10 * 1000)) / 1000;
|
|
|
|
ret[7] = '.';
|
|
|
|
ret[8] = '0' + (time % 1000) / 100;
|
|
|
|
ret[9] = '0' + (time % 100) / 10;
|
|
|
|
if (msPrecision)
|
|
|
|
ret[10] = '0' + time % 10;
|
|
|
|
return ret;
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
|
2011-12-22 22:28:41 +01:00
|
|
|
int AssTime::GetTimeHours() const { return time / 3600000; }
|
|
|
|
int AssTime::GetTimeMinutes() const { return (time % 3600000) / 60000; }
|
|
|
|
int AssTime::GetTimeSeconds() const { return (time % 60000) / 1000; }
|
|
|
|
int AssTime::GetTimeMiliseconds() const { return (time % 1000); }
|
|
|
|
int AssTime::GetTimeCentiseconds() const { return (time % 1000) / 10; }
|
2009-05-10 05:50:58 +02:00
|
|
|
|
2013-01-04 16:01:50 +01:00
|
|
|
SmpteFormatter::SmpteFormatter(agi::vfr::Framerate fps, std::string const& sep)
|
2011-12-22 22:28:13 +01:00
|
|
|
: fps(fps)
|
2012-03-29 21:04:36 +02:00
|
|
|
, sep(sep)
|
2011-12-22 22:22:49 +01:00
|
|
|
{
|
2009-05-10 05:50:58 +02:00
|
|
|
}
|
|
|
|
|
2013-01-04 16:01:50 +01:00
|
|
|
std::string SmpteFormatter::ToSMPTE(AssTime time) const {
|
2012-03-29 21:04:36 +02:00
|
|
|
int h=0, m=0, s=0, f=0;
|
|
|
|
fps.SmpteAtTime(time, &h, &m, &s, &f);
|
2013-01-04 16:01:50 +01:00
|
|
|
return str(boost::format("%02d%s%02d%s%02d%c%02d") % h % sep % m % sep % s % sep % f);
|
2012-03-29 21:04:36 +02:00
|
|
|
}
|
2009-05-13 22:24:21 +02:00
|
|
|
|
2013-01-04 16:01:50 +01:00
|
|
|
AssTime SmpteFormatter::FromSMPTE(std::string const& str) const {
|
|
|
|
std::vector<std::string> toks;
|
|
|
|
boost::split(toks, str, boost::is_any_of(sep));
|
2012-03-29 21:04:36 +02:00
|
|
|
if (toks.size() != 4) return 0;
|
2013-01-04 16:01:50 +01:00
|
|
|
|
|
|
|
int h, m, s, f;
|
|
|
|
agi::util::try_parse(toks[0], &h);
|
|
|
|
agi::util::try_parse(toks[1], &m);
|
|
|
|
agi::util::try_parse(toks[2], &s);
|
|
|
|
agi::util::try_parse(toks[3], &f);
|
2012-03-29 21:04:36 +02:00
|
|
|
return fps.TimeAtSmpte(h, m, s, f);
|
2009-05-10 05:50:58 +02:00
|
|
|
}
|