forked from mia/Aegisub
Untested PRS loading implemented (still doesn't parse data blocks, though)
Originally committed to SVN as r260.
This commit is contained in:
parent
5682ca97b4
commit
68cd073396
7 changed files with 172 additions and 35 deletions
|
@ -115,16 +115,17 @@ void PRSSubtitleFormat::WriteFile(wxString filename,wxString encoding) {
|
||||||
// Convert to PNG
|
// Convert to PNG
|
||||||
int x=0,y=0;
|
int x=0,y=0;
|
||||||
wxImage bmp = CalculateAlpha(frame1->GetReadPtr(),frame2->GetReadPtr(),frame1->GetRowSize(),frame1->GetHeight(),frame1->GetPitch(),&x,&y);
|
wxImage bmp = CalculateAlpha(frame1->GetReadPtr(),frame2->GetReadPtr(),frame1->GetRowSize(),frame1->GetHeight(),frame1->GetPitch(),&x,&y);
|
||||||
//RAMOutputStream stream;
|
if (!bmp.Ok()) continue;
|
||||||
wxMemoryOutputStream stream;
|
wxMemoryOutputStream stream;
|
||||||
bmp.SaveFile(stream,wxBITMAP_TYPE_PNG);
|
bmp.SaveFile(stream,wxBITMAP_TYPE_PNG);
|
||||||
//bmp.SaveFile(filename + wxString::Format(_T("%i.png"),id),wxBITMAP_TYPE_PNG);
|
bmp.SaveFile(filename + wxString::Format(_T("%i.png"),id),wxBITMAP_TYPE_PNG);
|
||||||
|
|
||||||
// Create PRSImage
|
// Create PRSImage
|
||||||
PRSImage *img = new PRSImage;
|
PRSImage *img = new PRSImage;
|
||||||
img->id = id;
|
img->id = id;
|
||||||
img->dataLen = stream.GetSize();
|
img->dataLen = stream.GetSize();
|
||||||
img->data = new char[img->dataLen];
|
img->data = new char[img->dataLen];
|
||||||
|
img->imageType = PNG_IMG;
|
||||||
stream.CopyTo(img->data,img->dataLen);
|
stream.CopyTo(img->data,img->dataLen);
|
||||||
|
|
||||||
// Create PRSDisplay
|
// Create PRSDisplay
|
||||||
|
@ -182,8 +183,8 @@ wxImage PRSSubtitleFormat::CalculateAlpha(const unsigned char* frame1, const uns
|
||||||
int maxy = 0;
|
int maxy = 0;
|
||||||
|
|
||||||
// Process
|
// Process
|
||||||
int r1,g1,b1,r2,g2,b2;
|
unsigned char r1,g1,b1,r2,g2,b2;
|
||||||
int r,g,b,a;
|
unsigned char r,g,b,a;
|
||||||
for (int y=h;--y>=0;) {
|
for (int y=h;--y>=0;) {
|
||||||
for (int x=0;x<w;x+=4) {
|
for (int x=0;x<w;x+=4) {
|
||||||
// Read pixels
|
// Read pixels
|
||||||
|
@ -231,16 +232,21 @@ wxImage PRSSubtitleFormat::CalculateAlpha(const unsigned char* frame1, const uns
|
||||||
dsta -= w/2;
|
dsta -= w/2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calculate sizes
|
||||||
|
minx /= 4;
|
||||||
|
maxx /= 4;
|
||||||
|
if (dstx) *dstx = minx;
|
||||||
|
if (dsty) *dsty = miny;
|
||||||
|
int width = maxx-minx+1;
|
||||||
|
int height = maxy-miny+1;
|
||||||
|
if (width <= 0 || height <= 0) return wxImage();
|
||||||
|
|
||||||
// Create the actual image
|
// Create the actual image
|
||||||
wxImage img(w/4,h,data,false);
|
wxImage img(w/4,h,data,false);
|
||||||
img.SetAlpha(alpha,false);
|
img.SetAlpha(alpha,false);
|
||||||
|
|
||||||
// Return subimage
|
// Return subimage
|
||||||
minx /= 4;
|
wxImage subimg = SubImageWithAlpha(img,wxRect(minx,miny,width,height));
|
||||||
maxx /= 4;
|
|
||||||
if (dstx) *dstx = minx;
|
|
||||||
if (dsty) *dsty = miny;
|
|
||||||
wxImage subimg = SubImageWithAlpha(img,wxRect(minx,miny,maxx-minx+1,maxy-miny+1));
|
|
||||||
return subimg;
|
return subimg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,43 +61,64 @@ PRSDisplay::~PRSDisplay() {
|
||||||
|
|
||||||
//////////////
|
//////////////
|
||||||
// Write data
|
// Write data
|
||||||
void PRSDisplay::WriteData(FILE *fp) {
|
void PRSDisplay::WriteData(std::vector<char> &vec) {
|
||||||
|
// Set length
|
||||||
|
unsigned __int32 utemp = 4 + 4 + 4 + 2 + 2 + 2 + 1 + 1;
|
||||||
|
vec.resize(utemp+8);
|
||||||
|
size_t pos = 0;
|
||||||
|
|
||||||
// Write block identifier
|
// Write block identifier
|
||||||
fwrite("DSP",1,4,fp);
|
char str[] = "DSP";
|
||||||
|
memcpy(&vec[pos],str,4);
|
||||||
|
pos += 4;
|
||||||
|
|
||||||
// Write block length
|
// Write block length
|
||||||
unsigned __int32 utemp = 4 + 4 + 4 + 2 + 2 + 2 + 1 + 1;
|
memcpy(&vec[pos],&utemp,4);
|
||||||
fwrite(&utemp,4,1,fp);
|
pos += 4;
|
||||||
|
|
||||||
// Write start time
|
// Write start time
|
||||||
utemp = start;
|
utemp = start;
|
||||||
fwrite(&utemp,4,1,fp);
|
memcpy(&vec[pos],&utemp,4);
|
||||||
|
pos += 4;
|
||||||
|
|
||||||
// Write end time
|
// Write end time
|
||||||
utemp = end;
|
utemp = end;
|
||||||
fwrite(&utemp,4,1,fp);
|
memcpy(&vec[pos],&utemp,4);
|
||||||
|
pos += 4;
|
||||||
|
|
||||||
// Write image identifier
|
// Write image identifier
|
||||||
utemp = id;
|
utemp = id;
|
||||||
fwrite(&utemp,4,1,fp);
|
memcpy(&vec[pos],&utemp,4);
|
||||||
|
pos += 4;
|
||||||
|
|
||||||
// Write layer
|
// Write layer
|
||||||
__int16 shorttemp = layer;
|
__int16 shorttemp = layer;
|
||||||
fwrite(&shorttemp,2,1,fp);
|
memcpy(&vec[pos],&shorttemp,2);
|
||||||
|
pos += 2;
|
||||||
|
|
||||||
// Write x
|
// Write x
|
||||||
shorttemp = x;
|
shorttemp = x;
|
||||||
fwrite(&shorttemp,2,1,fp);
|
memcpy(&vec[pos],&shorttemp,2);
|
||||||
|
pos += 2;
|
||||||
|
|
||||||
// Write y
|
// Write y
|
||||||
shorttemp = y;
|
shorttemp = y;
|
||||||
fwrite(&shorttemp,2,1,fp);
|
memcpy(&vec[pos],&shorttemp,2);
|
||||||
|
pos += 2;
|
||||||
|
|
||||||
// Write alpha multiplier
|
// Write alpha multiplier
|
||||||
unsigned __int8 chartemp = alpha;
|
unsigned __int8 chartemp = alpha;
|
||||||
fwrite(&chartemp,1,1,fp);
|
memcpy(&vec[pos],&chartemp,1);
|
||||||
|
pos += 1;
|
||||||
|
|
||||||
// Write blend mode
|
// Write blend mode
|
||||||
chartemp = blend;
|
chartemp = blend;
|
||||||
fwrite(&chartemp,1,1,fp);
|
memcpy(&vec[pos],&chartemp,1);
|
||||||
|
pos += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/////////////
|
||||||
|
// Read data
|
||||||
|
void PRSDisplay::ReadData(std::vector<char> &vec) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,7 @@ enum PRSBlendMode {
|
||||||
///////////
|
///////////
|
||||||
// Headers
|
// Headers
|
||||||
#include "prs_entry.h"
|
#include "prs_entry.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
/////////////////
|
/////////////////
|
||||||
|
@ -69,5 +70,6 @@ public:
|
||||||
~PRSDisplay();
|
~PRSDisplay();
|
||||||
|
|
||||||
PRSEntryType GetType() { return DISPLAY_ENTRY; }
|
PRSEntryType GetType() { return DISPLAY_ENTRY; }
|
||||||
void WriteData(FILE *fp);
|
void WriteData(std::vector<char> &vec);
|
||||||
|
void ReadData(std::vector<char> &vec);
|
||||||
};
|
};
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
///////////
|
///////////
|
||||||
// Headers
|
// Headers
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
//////////////
|
//////////////
|
||||||
|
@ -65,7 +66,7 @@ public:
|
||||||
virtual ~PRSEntry() {}
|
virtual ~PRSEntry() {}
|
||||||
|
|
||||||
virtual PRSEntryType GetType() { return BASE_ENTRY; }
|
virtual PRSEntryType GetType() { return BASE_ENTRY; }
|
||||||
virtual void WriteData(FILE *fp) { }
|
virtual void WriteData(std::vector<char> &vec) { }
|
||||||
|
|
||||||
static PRSImage* GetImage(PRSEntry* entry);
|
static PRSImage* GetImage(PRSEntry* entry);
|
||||||
static PRSDisplay* GetDisplay(PRSDisplay* entry);
|
static PRSDisplay* GetDisplay(PRSDisplay* entry);
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
///////////
|
///////////
|
||||||
// Headers
|
// Headers
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <vector>
|
||||||
#include "prs_file.h"
|
#include "prs_file.h"
|
||||||
#include "prs_entry.h"
|
#include "prs_entry.h"
|
||||||
#include "prs_image.h"
|
#include "prs_image.h"
|
||||||
|
@ -85,7 +86,7 @@ void PRSFile::Save(std::string path) {
|
||||||
fwrite("PRS",1,4,fp);
|
fwrite("PRS",1,4,fp);
|
||||||
|
|
||||||
// Write version number (4 bytes)
|
// Write version number (4 bytes)
|
||||||
__int32 temp = 1;
|
unsigned __int32 temp = 1;
|
||||||
fwrite(&temp,4,1,fp);
|
fwrite(&temp,4,1,fp);
|
||||||
|
|
||||||
// Write stream name (for future scalability, there is only one for now)
|
// Write stream name (for future scalability, there is only one for now)
|
||||||
|
@ -95,15 +96,23 @@ void PRSFile::Save(std::string path) {
|
||||||
fwrite(&temp,4,1,fp);
|
fwrite(&temp,4,1,fp);
|
||||||
|
|
||||||
// Write data blocks
|
// Write data blocks
|
||||||
|
std::vector<char> vec;
|
||||||
std::list<PRSEntry*>::iterator cur;
|
std::list<PRSEntry*>::iterator cur;
|
||||||
for (cur=entryList.begin();cur!=entryList.end();cur++) {
|
for (cur=entryList.begin();cur!=entryList.end();cur++) {
|
||||||
// Data blocks take care of writing themselves
|
// Data blocks take care of writing themselves
|
||||||
// All of them start with a 4-byte string identifier, and a 4-byte length identifier
|
// All of them start with a 4-byte string identifier, and a 4-byte length identifier
|
||||||
// A decoder can (and should!) ignore any block that it doesn't recognize
|
// A decoder can (and should!) ignore any block that it doesn't recognize
|
||||||
(*cur)->WriteData(fp);
|
vec.resize(0);
|
||||||
|
(*cur)->WriteData(vec);
|
||||||
|
fwrite(&vec[0],1,vec.size(),fp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (...) {}
|
|
||||||
|
// Rethrow exceptions
|
||||||
|
catch (...) {
|
||||||
|
fclose(fp);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
// Close file
|
// Close file
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
@ -113,6 +122,85 @@ void PRSFile::Save(std::string path) {
|
||||||
////////
|
////////
|
||||||
// Load
|
// Load
|
||||||
void PRSFile::Load(std::string path, bool reset) {
|
void PRSFile::Load(std::string path, bool reset) {
|
||||||
|
// Reset first, if requested
|
||||||
|
if (reset) Reset();
|
||||||
|
|
||||||
|
// Open file
|
||||||
|
FILE *fp = fopen(path.c_str(),"rb");
|
||||||
|
if (!fp) throw "Failed to open file";
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Read first four bytes
|
||||||
|
char buf[5];
|
||||||
|
buf[4] = 0;
|
||||||
|
fread(buf,1,4,fp);
|
||||||
|
if (strcmp(buf,"PRS") != 0) throw "Invalid file type.";
|
||||||
|
|
||||||
|
// Read version number
|
||||||
|
unsigned __int32 temp = 0;
|
||||||
|
fread(&temp,4,1,fp);
|
||||||
|
if (temp != 1) throw "Invalid version.";
|
||||||
|
|
||||||
|
// Read stream name length
|
||||||
|
fread(&temp,4,1,fp);
|
||||||
|
|
||||||
|
// Read stream name
|
||||||
|
if (temp > 0) {
|
||||||
|
char *streamName = new char[temp+1];
|
||||||
|
fread(streamName,1,temp,fp);
|
||||||
|
|
||||||
|
// We don't need it, so delete afterwards
|
||||||
|
delete streamName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Temporary vector
|
||||||
|
std::vector<char> vec;
|
||||||
|
|
||||||
|
// Read data blocks
|
||||||
|
while (!feof(fp)) {
|
||||||
|
// Read identifier and size
|
||||||
|
fread(buf,1,4,fp);
|
||||||
|
fread(&temp,4,1,fp);
|
||||||
|
|
||||||
|
// Image block
|
||||||
|
if (strcmp(buf,"IMG") == 0) {
|
||||||
|
// Read data
|
||||||
|
vec.resize(temp);
|
||||||
|
fread(&vec[0],1,temp,fp);
|
||||||
|
|
||||||
|
// Create object
|
||||||
|
PRSImage *img = new PRSImage;
|
||||||
|
img->ReadData(vec);
|
||||||
|
AddEntry(img);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display block
|
||||||
|
else if (strcmp(buf,"DSP") == 0) {
|
||||||
|
// Read data
|
||||||
|
vec.resize(temp);
|
||||||
|
fread(&vec[0],1,temp,fp);
|
||||||
|
|
||||||
|
// Create object
|
||||||
|
PRSDisplay *disp = new PRSDisplay;
|
||||||
|
disp->ReadData(vec);
|
||||||
|
AddEntry(disp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unknown block, ignore it
|
||||||
|
else {
|
||||||
|
fseek(fp,temp,SEEK_CUR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rethrow exceptions
|
||||||
|
catch (...) {
|
||||||
|
fclose(fp);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close file
|
||||||
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -62,26 +62,43 @@ PRSImage::~PRSImage() {
|
||||||
|
|
||||||
//////////////
|
//////////////
|
||||||
// Write data
|
// Write data
|
||||||
void PRSImage::WriteData(FILE *fp) {
|
void PRSImage::WriteData(std::vector<char> &vec) {
|
||||||
|
// Set length
|
||||||
|
unsigned __int32 utemp = 4 + 4 + 4 + dataLen;
|
||||||
|
vec.resize(utemp+8);
|
||||||
|
size_t pos = 0;
|
||||||
|
|
||||||
// Write block identifier
|
// Write block identifier
|
||||||
fwrite("IMG",1,4,fp);
|
char str[] = "IMG";
|
||||||
|
memcpy(&vec[pos],str,4);
|
||||||
|
pos += 4;
|
||||||
|
|
||||||
// Write block length
|
// Write block length
|
||||||
unsigned __int32 utemp = 4 + 4 + 4 + dataLen;
|
memcpy(&vec[pos],&utemp,4);
|
||||||
fwrite(&utemp,4,1,fp);
|
pos += 4;
|
||||||
|
|
||||||
// Write image identifier
|
// Write image identifier
|
||||||
utemp = id;
|
utemp = id;
|
||||||
fwrite(&utemp,4,1,fp);
|
memcpy(&vec[pos],&utemp,4);
|
||||||
|
pos += 4;
|
||||||
|
|
||||||
// Write image format
|
// Write image format
|
||||||
utemp = imageType;
|
utemp = imageType;
|
||||||
fwrite(&utemp,4,1,fp);
|
memcpy(&vec[pos],&utemp,4);
|
||||||
|
pos += 4;
|
||||||
|
|
||||||
// Write data length
|
// Write data length
|
||||||
utemp = dataLen;
|
utemp = dataLen;
|
||||||
fwrite(&utemp,4,1,fp);
|
memcpy(&vec[pos],&utemp,4);
|
||||||
|
pos += 4;
|
||||||
|
|
||||||
// Write data
|
// Write data
|
||||||
fwrite(data,1,dataLen,fp);
|
memcpy(&vec[pos],data,dataLen);
|
||||||
|
pos += dataLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/////////////
|
||||||
|
// Read data
|
||||||
|
void PRSImage::ReadData(std::vector<char> &vec) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
///////////
|
///////////
|
||||||
// Headers
|
// Headers
|
||||||
#include "prs_entry.h"
|
#include "prs_entry.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
///////////////
|
///////////////
|
||||||
|
@ -65,5 +66,6 @@ public:
|
||||||
~PRSImage();
|
~PRSImage();
|
||||||
|
|
||||||
PRSEntryType GetType() { return IMAGE_ENTRY; }
|
PRSEntryType GetType() { return IMAGE_ENTRY; }
|
||||||
void WriteData(FILE *fp);
|
void WriteData(std::vector<char> &vec);
|
||||||
|
void ReadData(std::vector<char> &vec);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue