source: OniSplit/SubtitleImporter.cs@ 1140

Last change on this file since 1140 was 1114, checked in by iritscen, 5 years ago

Adding OniSplit source code (v0.9.99.0). Many thanks to Neo for all his work over the years.

File size: 4.4 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.Text;
5
6namespace Oni
7{
8 internal sealed class SubtitleImporter : Importer
9 {
10 #region Private data
11 private List<byte> subtitles;
12 private List<int> offsets;
13 #endregion
14
15 public override void Import(string filePath, string outputDirPath)
16 {
17 ReadTextFile(filePath);
18
19 string name = Path.GetFileNameWithoutExtension(filePath);
20
21 BeginImport();
22 WriteSUBT(name, subtitles.ToArray());
23 Write(outputDirPath);
24 }
25
26 private void ReadTextFile(string filePath)
27 {
28 subtitles = new List<byte>();
29 offsets = new List<int>();
30
31 var data = File.ReadAllBytes(filePath);
32 int i = SkipPreamble(data);
33
34 while (i < data.Length)
35 {
36 int nameStart = i;
37
38 while (!IsNewLine(data, i) && data[i] != '=')
39 i++;
40
41 int nameEnd = i;
42
43 if (IsNewLine(data, i))
44 {
45 //
46 // This was an empty line or a line that does not contain a =. Skip it.
47 //
48
49 continue;
50 }
51
52 i++;
53
54 int textStart = i;
55
56 while (!IsNewLine(data, i))
57 i++;
58
59 int textEnd = i;
60
61 if (nameEnd > nameStart)
62 {
63 offsets.Add(subtitles.Count);
64
65 for (int j = nameStart; j < nameEnd; j++)
66 subtitles.Add(data[j]);
67
68 subtitles.Add(0);
69
70 for (int j = textStart; j < textEnd; j++)
71 subtitles.Add(data[j]);
72
73 subtitles.Add(0);
74 }
75
76 i = SkipNewLine(data, i);
77 }
78 }
79
80 private static int SkipPreamble(byte[] data)
81 {
82 int offset = CheckPreamble(data, Encoding.UTF8.GetPreamble());
83
84 if (offset > 0)
85 return offset;
86
87 if (CheckPreamble(data, Encoding.Unicode.GetPreamble()) != 0
88 || CheckPreamble(data, Encoding.BigEndianUnicode.GetPreamble()) != 0
89 || CheckPreamble(data, Encoding.UTF32.GetPreamble()) != 0)
90 {
91 throw new InvalidDataException("UTF16/32 input text files are not supported.");
92 }
93
94 if (data.Length >= 4)
95 {
96 if ((data[1] == 0 && data[3] == 0)
97 || (data[0] == 0 && data[2] == 0))
98 {
99 throw new InvalidDataException("UTF16/32 input text files are not supported.");
100 }
101 }
102
103 return 0;
104 }
105
106 private static int CheckPreamble(byte[] data, byte[] preamble)
107 {
108 if (data.Length < preamble.Length)
109 return 0;
110
111 for (int i = 0; i < preamble.Length; i++)
112 {
113 if (data[i] != preamble[i])
114 return 0;
115 }
116
117 return preamble.Length;
118 }
119
120 private static bool IsNewLine(byte[] data, int offset)
121 {
122 if (offset >= data.Length)
123 return true;
124
125 return (SkipNewLine(data, offset) > offset);
126 }
127
128 private static int SkipNewLine(byte[] data, int offset)
129 {
130 if (offset < data.Length)
131 {
132 if (data[offset] == '\n')
133 {
134 offset++;
135 }
136 else if (data[offset] == '\r')
137 {
138 offset++;
139
140 if (offset < data.Length && data[offset] == '\n')
141 offset++;
142 }
143 }
144
145 return offset;
146 }
147
148 private void WriteSUBT(string name, byte[] subtitles)
149 {
150 var subt = CreateInstance(TemplateTag.SUBT, name);
151
152 using (var writer = subt.OpenWrite(16))
153 {
154 writer.Write(WriteRawPart(subtitles));
155 writer.Write(offsets.Count);
156 writer.Write(offsets.ToArray());
157 }
158 }
159 }
160}
Note: See TracBrowser for help on using the repository browser.