forked from mia/Aegisub
Significantly clean up and simplify AssAttachment
Originally committed to SVN as r6038.
This commit is contained in:
parent
eaf436657e
commit
00bc0c7ef8
3 changed files with 50 additions and 218 deletions
|
@ -34,9 +34,6 @@
|
||||||
/// @ingroup subs_storage
|
/// @ingroup subs_storage
|
||||||
///
|
///
|
||||||
|
|
||||||
|
|
||||||
////////////
|
|
||||||
// Includes
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#ifndef AGI_PRE
|
#ifndef AGI_PRE
|
||||||
|
@ -46,87 +43,26 @@
|
||||||
|
|
||||||
#include "ass_attachment.h"
|
#include "ass_attachment.h"
|
||||||
|
|
||||||
|
AssAttachment::AssAttachment(wxString name)
|
||||||
|
: data(new std::vector<unsigned char>)
|
||||||
/// @brief Constructor
|
, filename(name)
|
||||||
/// @param _name
|
{
|
||||||
///
|
wxFileName fname(filename);
|
||||||
AssAttachment::AssAttachment(wxString _name) {
|
|
||||||
// Parse name
|
|
||||||
filename = _name;
|
|
||||||
wxFileName fname(GetFileName());
|
|
||||||
wxString ext = fname.GetExt().Lower();
|
wxString ext = fname.GetExt().Lower();
|
||||||
wxString name;
|
if (ext == "ttf")
|
||||||
if (ext == "ttf") {
|
filename = fname.GetName() + "_0." + ext;
|
||||||
name = fname.GetName() + "_0." + ext;
|
|
||||||
}
|
|
||||||
else name = _name;
|
|
||||||
|
|
||||||
// Set data
|
|
||||||
filename = name;
|
|
||||||
data = std::tr1::shared_ptr<AttachData> (new AttachData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief Destructor
|
|
||||||
///
|
|
||||||
AssAttachment::~AssAttachment() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief Clone
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
AssEntry *AssAttachment::Clone() const {
|
AssEntry *AssAttachment::Clone() const {
|
||||||
// New object
|
|
||||||
AssAttachment *clone = new AssAttachment(filename);
|
AssAttachment *clone = new AssAttachment(filename);
|
||||||
|
|
||||||
// Copy fields
|
|
||||||
clone->data = data;
|
clone->data = data;
|
||||||
clone->group = group;
|
clone->group = group;
|
||||||
|
|
||||||
// Return
|
|
||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief Get data
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
const DataVec &AssAttachment::GetData() {
|
|
||||||
return data->GetData();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief Add more data
|
|
||||||
/// @param _data
|
|
||||||
///
|
|
||||||
void AssAttachment::AddData(wxString _data) {
|
|
||||||
data->AddData(_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief Finish adding data
|
|
||||||
///
|
|
||||||
void AssAttachment::Finish() {
|
|
||||||
data->Finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief Get encoded data to write on file
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
const wxString AssAttachment::GetEntryData() const {
|
const wxString AssAttachment::GetEntryData() const {
|
||||||
// Get data
|
|
||||||
const DataVec &dat = data->GetData();
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
int size = dat.size();
|
int size = data->size();
|
||||||
int written = 0;
|
int written = 0;
|
||||||
unsigned char src[3];
|
unsigned char src[3];
|
||||||
unsigned char dst[4];
|
unsigned char dst[4];
|
||||||
|
@ -144,10 +80,10 @@ const wxString AssAttachment::GetEntryData() const {
|
||||||
if (read > 3) read = 3;
|
if (read > 3) read = 3;
|
||||||
|
|
||||||
// Read source
|
// Read source
|
||||||
src[0] = dat[pos];
|
src[0] = (*data)[pos];
|
||||||
if (read >= 2) src[1] = dat[pos+1];
|
if (read >= 2) src[1] = (*data)[pos+1];
|
||||||
else src[1] = 0;
|
else src[1] = 0;
|
||||||
if (read == 3) src[2] = dat[pos+2];
|
if (read == 3) src[2] = (*data)[pos+2];
|
||||||
else src[2] = 0;
|
else src[2] = 0;
|
||||||
pos += read;
|
pos += read;
|
||||||
|
|
||||||
|
@ -173,32 +109,16 @@ const wxString AssAttachment::GetEntryData() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return
|
|
||||||
return entryData;
|
return entryData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief Extract as a file
|
|
||||||
/// @param filename
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
void AssAttachment::Extract(wxString filename) {
|
void AssAttachment::Extract(wxString filename) {
|
||||||
// Open file
|
|
||||||
wxFileOutputStream fp(filename);
|
wxFileOutputStream fp(filename);
|
||||||
if (!fp.Ok()) return;
|
if (!fp.Ok()) return;
|
||||||
fp.Write(&data->GetData()[0],data->GetData().size());
|
fp.Write(&(*data)[0], data->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief Read a file as attachment
|
|
||||||
/// @param filename
|
|
||||||
///
|
|
||||||
void AssAttachment::Import(wxString filename) {
|
void AssAttachment::Import(wxString filename) {
|
||||||
// Data
|
|
||||||
DataVec &datavec = data->GetData();
|
|
||||||
|
|
||||||
// Open file and get size
|
// Open file and get size
|
||||||
wxFileInputStream fp(filename);
|
wxFileInputStream fp(filename);
|
||||||
if (!fp.Ok()) throw "Failed opening file";
|
if (!fp.Ok()) throw "Failed opening file";
|
||||||
|
@ -206,102 +126,38 @@ void AssAttachment::Import(wxString filename) {
|
||||||
fp.SeekI(0,wxFromStart);
|
fp.SeekI(0,wxFromStart);
|
||||||
|
|
||||||
// Set size and read
|
// Set size and read
|
||||||
datavec.resize(size);
|
data->resize(size);
|
||||||
fp.Read(&datavec[0],size);
|
fp.Read(&(*data)[0],size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief Get filename
|
|
||||||
/// @param raw
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
wxString AssAttachment::GetFileName(bool raw) {
|
wxString AssAttachment::GetFileName(bool raw) {
|
||||||
// Raw
|
|
||||||
if (raw || filename.Right(4).Lower() != ".ttf") return filename;
|
if (raw || filename.Right(4).Lower() != ".ttf") return filename;
|
||||||
|
|
||||||
// Remove stuff after last underscore if it's a font
|
// Remove stuff after last underscore if it's a font
|
||||||
int lastUnder = -1;
|
wxString::size_type last_under = filename.rfind('_');
|
||||||
for (size_t i=0;i<filename.Length();i++) {
|
if (last_under == wxString::npos)
|
||||||
if (filename[i] == '_') lastUnder = i;
|
return filename;
|
||||||
}
|
|
||||||
|
|
||||||
// Underline found
|
return filename.Left(last_under) + ".ttf";
|
||||||
wxString final = filename;
|
|
||||||
if (lastUnder != -1) {
|
|
||||||
final = filename.Left(lastUnder) + ".ttf";
|
|
||||||
}
|
|
||||||
return final;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AssAttachment::Finish() {
|
||||||
|
|
||||||
|
|
||||||
/// @brief Constructor Attachment //////////////////
|
|
||||||
///
|
|
||||||
AttachData::AttachData() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief Destructor
|
|
||||||
///
|
|
||||||
AttachData::~AttachData() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief Get data
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
DataVec &AttachData::GetData() {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief Add data
|
|
||||||
/// @param data
|
|
||||||
///
|
|
||||||
void AttachData::AddData(wxString data) {
|
|
||||||
buffer += data;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief Finish
|
|
||||||
///
|
|
||||||
void AttachData::Finish() {
|
|
||||||
// Source and dest buffers
|
// Source and dest buffers
|
||||||
unsigned char src[4];
|
unsigned char src[4];
|
||||||
unsigned char dst[3];
|
unsigned char dst[3];
|
||||||
int bufPos = 0;
|
|
||||||
bool ok = true;
|
data->reserve(buffer.size() * 3 / 4);
|
||||||
|
|
||||||
// Read buffer
|
// Read buffer
|
||||||
while (ok) {
|
for(size_t pos = 0; pos + 1 < buffer.size(); ) {
|
||||||
// Find characters left
|
// Find characters left
|
||||||
int read = buffer.Length() - bufPos;
|
size_t read = std::min<size_t>(buffer.size() - pos, 4);
|
||||||
if (read > 4) read = 4;
|
|
||||||
int nbytes;
|
|
||||||
|
|
||||||
// At least four, proceed normally
|
// Move 4 bytes from buffer to src
|
||||||
if (read >= 2) {
|
for (size_t i = 0; i < read; ++i)
|
||||||
// Move 4 bytes from buffer to src
|
src[i] = (unsigned char)buffer[pos++] - 33;
|
||||||
for (int i=0;i<read;i++) {
|
for (size_t i = read; i < 4; ++i)
|
||||||
src[i] = (unsigned char) buffer[bufPos] - 33;
|
src[i] = 0;
|
||||||
bufPos++;
|
|
||||||
}
|
|
||||||
for (int i=read;i<4;i++) src[i] = 0;
|
|
||||||
ok = true;
|
|
||||||
nbytes = read-1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Zero, end
|
|
||||||
else {
|
|
||||||
ok = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert the 4 bytes from source to 3 in dst
|
// Convert the 4 bytes from source to 3 in dst
|
||||||
dst[0] = (src[0] << 2) | (src[1] >> 4);
|
dst[0] = (src[0] << 2) | (src[1] >> 4);
|
||||||
|
@ -309,14 +165,10 @@ void AttachData::Finish() {
|
||||||
dst[2] = ((src[2] & 0x3) << 6) | (src[3]);
|
dst[2] = ((src[2] & 0x3) << 6) | (src[3]);
|
||||||
|
|
||||||
// Push into vector
|
// Push into vector
|
||||||
size_t size = data.size();
|
copy(dst, dst + read - 1, back_inserter(*data));
|
||||||
data.resize(size+nbytes);
|
|
||||||
for (int i=0;i<nbytes;i++) data[size+i] = dst[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear buffer
|
// Clear buffer
|
||||||
buffer.Clear();
|
buffer.clear();
|
||||||
buffer.Shrink();
|
buffer.Shrink();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -34,9 +34,6 @@
|
||||||
/// @ingroup subs_storage
|
/// @ingroup subs_storage
|
||||||
///
|
///
|
||||||
|
|
||||||
|
|
||||||
///////////
|
|
||||||
// Headers
|
|
||||||
#ifndef AGI_PRE
|
#ifndef AGI_PRE
|
||||||
#include <tr1/memory>
|
#include <tr1/memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -44,60 +41,43 @@
|
||||||
|
|
||||||
#include "ass_entry.h"
|
#include "ass_entry.h"
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
typedef std::vector<unsigned char> DataVec;
|
|
||||||
|
|
||||||
|
|
||||||
/// @class AttachData
|
|
||||||
/// @brief DOCME
|
|
||||||
class AttachData {
|
|
||||||
private:
|
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
DataVec data;
|
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
wxString buffer;
|
|
||||||
|
|
||||||
public:
|
|
||||||
AttachData();
|
|
||||||
~AttachData();
|
|
||||||
|
|
||||||
DataVec &GetData();
|
|
||||||
void AddData(wxString data);
|
|
||||||
void Finish();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// @class AssAttachment
|
/// @class AssAttachment
|
||||||
/// @brief DOCME
|
/// @brief DOCME
|
||||||
class AssAttachment : public AssEntry {
|
class AssAttachment : public AssEntry {
|
||||||
private:
|
/// Decoded file data
|
||||||
|
std::tr1::shared_ptr<std::vector<unsigned char> > data;
|
||||||
|
|
||||||
/// DOCME
|
/// Encoded data which has been read from the script but not yet decoded
|
||||||
std::tr1::shared_ptr<AttachData> data;
|
wxString buffer;
|
||||||
|
|
||||||
/// DOCME
|
/// Name of the attached file, with SSA font mangling if it is a ttf
|
||||||
wxString filename;
|
wxString filename;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const DataVec &GetData();
|
/// Get the size of the attached file in bytes
|
||||||
|
size_t GetSize() const { return data->size(); }
|
||||||
|
|
||||||
void AddData(wxString data);
|
/// Add a line of data (without newline) read from a subtitle file to the
|
||||||
|
/// buffer waiting to be decoded
|
||||||
|
void AddData(wxString data) { buffer += data; }
|
||||||
|
/// Decode all data passed with AddData
|
||||||
void Finish();
|
void Finish();
|
||||||
|
|
||||||
|
/// Extract the contents of this attachment to a file
|
||||||
|
/// @param filename Path to save the attachment to
|
||||||
void Extract(wxString filename);
|
void Extract(wxString filename);
|
||||||
|
|
||||||
|
/// Import the contents of a file as an attachment
|
||||||
|
/// @param filename Path to import
|
||||||
void Import(wxString filename);
|
void Import(wxString filename);
|
||||||
|
|
||||||
|
/// Get the name of the attached file
|
||||||
|
/// @param raw If false, remove the SSA filename mangling
|
||||||
wxString GetFileName(bool raw=false);
|
wxString GetFileName(bool raw=false);
|
||||||
|
|
||||||
const wxString GetEntryData() const;
|
const wxString GetEntryData() const;
|
||||||
|
|
||||||
/// @brief DOCME
|
|
||||||
///
|
|
||||||
ASS_EntryType GetType() const { return ENTRY_ATTACHMENT; }
|
ASS_EntryType GetType() const { return ENTRY_ATTACHMENT; }
|
||||||
AssEntry *Clone() const;
|
AssEntry *Clone() const;
|
||||||
|
|
||||||
AssAttachment(wxString name);
|
AssAttachment(wxString name);
|
||||||
~AssAttachment();
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -117,7 +117,7 @@ void DialogAttachments::UpdateList() {
|
||||||
// Add item
|
// Add item
|
||||||
int row = listView->GetItemCount();
|
int row = listView->GetItemCount();
|
||||||
listView->InsertItem(row,attach->GetFileName(true));
|
listView->InsertItem(row,attach->GetFileName(true));
|
||||||
listView->SetItem(row,1,PrettySize(attach->GetData().size()));
|
listView->SetItem(row,1,PrettySize(attach->GetSize()));
|
||||||
listView->SetItem(row,2,attach->group);
|
listView->SetItem(row,2,attach->group);
|
||||||
listView->SetItemPtrData(row,wxPtrToUInt(attach));
|
listView->SetItemPtrData(row,wxPtrToUInt(attach));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue