~ubuntu-branches/ubuntu/trusty/aegisub/trusty

« back to all changes in this revision

Viewing changes to src/subtitle_format_microdvd.cpp

  • Committer: Package Import Robot
  • Author(s): Sebastian Reichel
  • Date: 2012-03-16 22:58:00 UTC
  • Revision ID: package-import@ubuntu.com-20120316225800-yfb8h9e5n04rk46a
Tags: upstream-2.1.9
ImportĀ upstreamĀ versionĀ 2.1.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (c) 2006, Rodrigo Braz Monteiro
 
2
// All rights reserved.
 
3
//
 
4
// Redistribution and use in source and binary forms, with or without
 
5
// modification, are permitted provided that the following conditions are met:
 
6
//
 
7
//   * Redistributions of source code must retain the above copyright notice,
 
8
//     this list of conditions and the following disclaimer.
 
9
//   * Redistributions in binary form must reproduce the above copyright notice,
 
10
//     this list of conditions and the following disclaimer in the documentation
 
11
//     and/or other materials provided with the distribution.
 
12
//   * Neither the name of the Aegisub Group nor the names of its contributors
 
13
//     may be used to endorse or promote products derived from this software
 
14
//     without specific prior written permission.
 
15
//
 
16
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 
17
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
18
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
19
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 
20
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 
21
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
22
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 
23
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 
24
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
25
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
26
// POSSIBILITY OF SUCH DAMAGE.
 
27
//
 
28
// -----------------------------------------------------------------------------
 
29
//
 
30
// AEGISUB
 
31
//
 
32
// Website: http://aegisub.cellosoft.com
 
33
// Contact: mailto:zeratul@cellosoft.com
 
34
//
 
35
 
 
36
 
 
37
///////////
 
38
// Headers
 
39
#include "config.h"
 
40
 
 
41
#include "subtitle_format_microdvd.h"
 
42
#include "ass_dialogue.h"
 
43
#include "ass_time.h"
 
44
#include "text_file_reader.h"
 
45
#include "text_file_writer.h"
 
46
#include "vfr.h"
 
47
#include <wx/regex.h>
 
48
 
 
49
 
 
50
///////////////////
 
51
// Get format name
 
52
wxString MicroDVDSubtitleFormat::GetName() {
 
53
        return _T("MicroDVD");
 
54
}
 
55
 
 
56
 
 
57
//////////////////////
 
58
// Get read wildcards
 
59
wxArrayString MicroDVDSubtitleFormat::GetReadWildcards() {
 
60
        wxArrayString formats;
 
61
        formats.Add(_T("sub"));
 
62
        return formats;
 
63
}
 
64
 
 
65
 
 
66
///////////////////////
 
67
// Get write wildcards
 
68
wxArrayString MicroDVDSubtitleFormat::GetWriteWildcards() {
 
69
        return GetReadWildcards();
 
70
}
 
71
 
 
72
 
 
73
////////////////////
 
74
// Can read a file?
 
75
bool MicroDVDSubtitleFormat::CanReadFile(wxString filename) {
 
76
        // Return false immediately if extension is wrong
 
77
        if (filename.Right(4).Lower() != _T(".sub")) return false;
 
78
 
 
79
        // Since there is an infinity of .sub formats, load first line and check if it's valid
 
80
        TextFileReader file(filename);
 
81
        if (file.HasMoreLines() && !file.SmellsBinary()) {
 
82
                wxRegEx exp(_T("^[\\{\\[]([0-9]+)[\\}\\]][\\{\\[]([0-9]+)[\\}\\]](.*)$"),wxRE_ADVANCED);
 
83
                return exp.Matches(file.ReadLineFromFile());
 
84
        }
 
85
 
 
86
        return false;
 
87
}
 
88
 
 
89
 
 
90
/////////////////////
 
91
// Can write a file?
 
92
bool MicroDVDSubtitleFormat::CanWriteFile(wxString filename) {
 
93
        return (filename.Right(4).Lower() == _T(".sub"));
 
94
}
 
95
 
 
96
 
 
97
DEFINE_SIMPLE_EXCEPTION(MicrodvdFormatParseError, SubtitleFormatParseError, "subtitle_io/parse/microdvd")
 
98
 
 
99
///////////////
 
100
// Read a file
 
101
void MicroDVDSubtitleFormat::ReadFile(wxString filename,wxString forceEncoding) {
 
102
        // Load and prepare regexp
 
103
        TextFileReader file(filename, forceEncoding);
 
104
        wxRegEx exp(_T("^[\\{\\[]([0-9]+)[\\}\\]][\\{\\[]([0-9]+)[\\}\\]](.*)$"),wxRE_ADVANCED);
 
105
 
 
106
        if (file.SmellsBinary())
 
107
                throw new MicrodvdFormatParseError(_T("File seems to be binary. Maybe it's a VobSub format file? (Aegisub does not support VobSub format.)"), 0);
 
108
 
 
109
        // Load default
 
110
        LoadDefault(false);
 
111
 
 
112
        // Prepare conversion
 
113
        FrameRate cfr;
 
114
        FrameRate *rate = &cfr;
 
115
 
 
116
        // Loop
 
117
        bool isFirst = true;
 
118
        FPSRational fps_rat;
 
119
        double fps = 0.0;
 
120
        while (file.HasMoreLines()) {
 
121
                wxString line = file.ReadLineFromFile();
 
122
                if (exp.Matches(line)) {
 
123
                        // Parse
 
124
                        long f1,f2;
 
125
                        exp.GetMatch(line,1).ToLong(&f1);
 
126
                        exp.GetMatch(line,2).ToLong(&f2);
 
127
                        wxString text = exp.GetMatch(line,3);
 
128
 
 
129
                        // If it's the first, check if it contains fps information
 
130
                        if (isFirst) {
 
131
                                if (f1 == 1 && f2 == 1) {
 
132
                                        // Convert fps
 
133
                                        try {
 
134
                                                text.ToDouble(&fps);
 
135
                                        }
 
136
                                        catch (...) {}
 
137
                                }
 
138
                                isFirst = false;
 
139
 
 
140
                                // If it wasn't an fps line, ask the user for it
 
141
                                if (fps <= 0.0) {
 
142
                                        fps_rat = AskForFPS();
 
143
                                        if (fps_rat.num == 0) return;
 
144
                                        else if (fps_rat.num > 0) cfr.SetCFR(double(fps_rat.num)/double(fps_rat.den));
 
145
                                        else rate = &VFR_Output;
 
146
                                }
 
147
                                else {
 
148
                                        cfr.SetCFR(fps);
 
149
                                        continue;
 
150
                                }
 
151
                        }
 
152
 
 
153
                        // Start and end times
 
154
                        int start,end;
 
155
                        start = rate->GetTimeAtFrame(f1,true);
 
156
                        end = rate->GetTimeAtFrame(f2,false);
 
157
 
 
158
                        // Process text
 
159
                        text.Replace(_T("|"),_T("\\N"));
 
160
 
 
161
                        // Create and insert line
 
162
                        AssDialogue *line = new AssDialogue();
 
163
                        line->group = _T("[Events]");
 
164
                        line->Style = _T("Default");
 
165
                        line->SetStartMS(start);
 
166
                        line->SetEndMS(end);
 
167
                        line->Text = text;
 
168
                        Line->push_back(line);
 
169
                }
 
170
        }
 
171
}
 
172
 
 
173
 
 
174
////////////////
 
175
// Write a file
 
176
void MicroDVDSubtitleFormat::WriteFile(wxString filename,wxString encoding) {
 
177
        // Set FPS
 
178
        FrameRate cfr;
 
179
        FrameRate *rate = &cfr;
 
180
        FPSRational fps_rat = AskForFPS();
 
181
        if (fps_rat.num == 0 || fps_rat.den == 0) return;
 
182
        double fps = double(fps_rat.num) / double(fps_rat.den);
 
183
        if (fps > 0.0) cfr.SetCFR(fps);
 
184
        else rate = &VFR_Output;
 
185
 
 
186
        // Convert file
 
187
        CreateCopy();
 
188
        SortLines();
 
189
        StripComments();
 
190
        RecombineOverlaps();
 
191
        MergeIdentical();
 
192
        ConvertTags(1,_T("|"));
 
193
 
 
194
        // Open file
 
195
        TextFileWriter file(filename,encoding);
 
196
 
 
197
        // Write FPS line
 
198
        if (rate->GetFrameRateType() != VFR) {
 
199
                file.WriteLineToFile(wxString::Format(_T("{1}{1}%.6f"),rate->GetAverage()));
 
200
        }
 
201
 
 
202
        // Write lines
 
203
        using std::list;
 
204
        for (list<AssEntry*>::iterator cur=Line->begin();cur!=Line->end();cur++) {
 
205
                AssDialogue *current = AssEntry::GetAsDialogue(*cur);
 
206
                if (current && !current->Comment) {
 
207
                        // Prepare data
 
208
                        int start = rate->GetFrameAtTime(current->Start.GetMS(),true);
 
209
                        int end = rate->GetFrameAtTime(current->End.GetMS(),false);
 
210
 
 
211
                        // Write data
 
212
                        file.WriteLineToFile(wxString::Format(_T("{%i}{%i}%s"),start,end,current->Text.c_str()));
 
213
                }
 
214
        }
 
215
 
 
216
        // Clean up
 
217
        ClearCopy();
 
218
}