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

« back to all changes in this revision

Viewing changes to src/ass_attachment.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
// Includes
 
39
#include "config.h"
 
40
 
 
41
#include <wx/wfstream.h>
 
42
#include <wx/filename.h>
 
43
#include "ass_attachment.h"
 
44
 
 
45
 
 
46
///////////////
 
47
// Constructor
 
48
AssAttachment::AssAttachment(wxString _name) {
 
49
        // Parse name
 
50
        filename = _name;
 
51
        wxFileName fname(GetFileName());
 
52
        wxString ext = fname.GetExt().Lower();
 
53
        wxString name;
 
54
        if (ext == _T("ttf")) {
 
55
                name = fname.GetName() + _T("_0.") + ext;
 
56
        }
 
57
        else name = _name;
 
58
 
 
59
        // Set data
 
60
        filename = name;
 
61
        data = boost::shared_ptr<AttachData> (new AttachData);
 
62
}
 
63
 
 
64
 
 
65
//////////////
 
66
// Destructor
 
67
AssAttachment::~AssAttachment() {
 
68
}
 
69
 
 
70
 
 
71
/////////
 
72
// Clone
 
73
AssEntry *AssAttachment::Clone() const {
 
74
        // New object
 
75
        AssAttachment *clone = new AssAttachment(filename);
 
76
 
 
77
        // Copy fields
 
78
        clone->data = data;
 
79
        clone->group = group;
 
80
 
 
81
        // Return
 
82
        return clone;
 
83
}
 
84
 
 
85
 
 
86
////////////
 
87
// Get data
 
88
const DataVec &AssAttachment::GetData() {
 
89
        return data->GetData();
 
90
}
 
91
 
 
92
 
 
93
/////////////////
 
94
// Add more data
 
95
void AssAttachment::AddData(wxString _data) {
 
96
        data->AddData(_data);
 
97
}
 
98
 
 
99
 
 
100
//////////////////////
 
101
// Finish adding data
 
102
void AssAttachment::Finish() {
 
103
        data->Finish();
 
104
}
 
105
 
 
106
 
 
107
/////////////////////////////////////
 
108
// Get encoded data to write on file
 
109
const wxString AssAttachment::GetEntryData() {
 
110
        // Get data
 
111
        const DataVec &dat = data->GetData();
 
112
        int pos = 0;
 
113
        int size = dat.size();
 
114
        int written = 0;
 
115
        unsigned char src[3];
 
116
        unsigned char dst[4];
 
117
 
 
118
        // Write header
 
119
        wxString entryData;
 
120
        if (group == _T("[Fonts]")) entryData = _T("fontname: ");
 
121
        else entryData = _T("filename: ");
 
122
        entryData += filename + _T("\r\n");
 
123
 
 
124
        // Read three bytes
 
125
        while (pos < size) {
 
126
                // Number to read
 
127
                int read = size - pos;
 
128
                if (read > 3) read = 3;
 
129
 
 
130
                // Read source
 
131
                src[0] = dat[pos];
 
132
                if (read >= 2) src[1] = dat[pos+1];
 
133
                else src[1] = 0;
 
134
                if (read == 3) src[2] = dat[pos+2];
 
135
                else src[2] = 0;
 
136
                pos += read;
 
137
 
 
138
                // Codify
 
139
                dst[0] = src[0] >> 2;
 
140
                dst[1] = ((src[0] & 0x3) << 4) | ((src[1] & 0xF0) >> 4);
 
141
                dst[2] = ((src[1] & 0xF) << 2) | ((src[2] & 0xC0) >> 6);
 
142
                dst[3] = src[2] & 0x3F;
 
143
 
 
144
                // Number to write
 
145
                int toWrite = read+1;
 
146
 
 
147
                // Convert to text
 
148
                for (int i=0;i<toWrite;i++) {
 
149
                        entryData += wxChar(dst[i]+33);
 
150
                        written++;
 
151
 
 
152
                        // Line break
 
153
                        if (written == 80 && pos < size) {
 
154
                                written = 0;
 
155
                                entryData += _T("\r\n");
 
156
                        }
 
157
                }
 
158
        }
 
159
 
 
160
        // Return
 
161
        return entryData;
 
162
}
 
163
 
 
164
 
 
165
/////////////////////
 
166
// Extract as a file
 
167
void AssAttachment::Extract(wxString filename) {
 
168
        // Open file
 
169
        wxFileOutputStream fp(filename);
 
170
        if (!fp.Ok()) return;
 
171
        fp.Write(&data->GetData()[0],data->GetData().size());
 
172
}
 
173
 
 
174
 
 
175
/////////////////////////////
 
176
// Read a file as attachment
 
177
void AssAttachment::Import(wxString filename) {
 
178
        // Data
 
179
        DataVec &datavec = data->GetData();
 
180
 
 
181
        // Open file and get size
 
182
        wxFileInputStream fp(filename);
 
183
        if (!fp.Ok()) throw _T("Failed opening file");
 
184
        int size = fp.SeekI(0,wxFromEnd);
 
185
        fp.SeekI(0,wxFromStart);
 
186
 
 
187
        // Set size and read
 
188
        datavec.resize(size);
 
189
        fp.Read(&datavec[0],size);
 
190
}
 
191
 
 
192
 
 
193
////////////////
 
194
// Get filename
 
195
wxString AssAttachment::GetFileName(bool raw) {
 
196
        // Raw
 
197
        if (raw || filename.Right(4).Lower() != _T(".ttf")) return filename;
 
198
 
 
199
        // Remove stuff after last underscore if it's a font
 
200
        int lastUnder = -1;
 
201
        for (size_t i=0;i<filename.Length();i++) {
 
202
                if (filename[i] == _T('_')) lastUnder = i;
 
203
        }
 
204
 
 
205
        // Underline found
 
206
        wxString final = filename;
 
207
        if (lastUnder != -1) {
 
208
                final = filename.Left(lastUnder) + _T(".ttf");
 
209
        }
 
210
        return final;
 
211
}
 
212
 
 
213
 
 
214
 
 
215
/////////////////// Attachment //////////////////
 
216
///////////////
 
217
// Constructor
 
218
AttachData::AttachData() {
 
219
}
 
220
 
 
221
 
 
222
//////////////
 
223
// Destructor
 
224
AttachData::~AttachData() {
 
225
}
 
226
 
 
227
 
 
228
////////////
 
229
// Get data
 
230
DataVec &AttachData::GetData() {
 
231
        return data;
 
232
}
 
233
 
 
234
 
 
235
////////////
 
236
// Add data
 
237
void AttachData::AddData(wxString data) {
 
238
        buffer += data;
 
239
}
 
240
 
 
241
 
 
242
//////////
 
243
// Finish
 
244
void AttachData::Finish() {
 
245
        // Source and dest buffers
 
246
        unsigned char src[4];
 
247
        unsigned char dst[3];
 
248
        int bufPos = 0;
 
249
        bool ok = true;
 
250
 
 
251
        // Read buffer
 
252
        while (ok) {
 
253
                // Find characters left
 
254
                int read = buffer.Length() - bufPos;
 
255
                if (read > 4) read = 4;
 
256
                int nbytes;
 
257
 
 
258
                // At least four, proceed normally
 
259
                if (read >= 2) {
 
260
                        // Move 4 bytes from buffer to src
 
261
                        for (int i=0;i<read;i++) {
 
262
                                src[i] = (unsigned char) buffer[bufPos] - 33;
 
263
                                bufPos++;
 
264
                        }
 
265
                        for (int i=read;i<4;i++) src[i] = 0;
 
266
                        ok = true;
 
267
                        nbytes = read-1;
 
268
                }
 
269
 
 
270
                // Zero, end
 
271
                else {
 
272
                        ok = false;
 
273
                        break;
 
274
                }
 
275
 
 
276
                // Convert the 4 bytes from source to 3 in dst
 
277
                dst[0] = (src[0] << 2) | (src[1] >> 4);
 
278
                dst[1] = ((src[1] & 0xF) << 4) | (src[2] >> 2);
 
279
                dst[2] = ((src[2] & 0x3) << 6) | (src[3]);
 
280
 
 
281
                // Push into vector
 
282
                size_t size = data.size(); 
 
283
                data.resize(size+nbytes);
 
284
                for (int i=0;i<nbytes;i++) data[size+i] = dst[i];
 
285
        }
 
286
 
 
287
        // Clear buffer
 
288
        buffer.Clear();
 
289
        buffer.Shrink();
 
290
}