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
|
||||
int x=0,y=0;
|
||||
wxImage bmp = CalculateAlpha(frame1->GetReadPtr(),frame2->GetReadPtr(),frame1->GetRowSize(),frame1->GetHeight(),frame1->GetPitch(),&x,&y);
|
||||
//RAMOutputStream stream;
|
||||
if (!bmp.Ok()) continue;
|
||||
wxMemoryOutputStream stream;
|
||||
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
|
||||
PRSImage *img = new PRSImage;
|
||||
img->id = id;
|
||||
img->dataLen = stream.GetSize();
|
||||
img->data = new char[img->dataLen];
|
||||
img->imageType = PNG_IMG;
|
||||
stream.CopyTo(img->data,img->dataLen);
|
||||
|
||||
// Create PRSDisplay
|
||||
|
@ -182,8 +183,8 @@ wxImage PRSSubtitleFormat::CalculateAlpha(const unsigned char* frame1, const uns
|
|||
int maxy = 0;
|
||||
|
||||
// Process
|
||||
int r1,g1,b1,r2,g2,b2;
|
||||
int r,g,b,a;
|
||||
unsigned char r1,g1,b1,r2,g2,b2;
|
||||
unsigned char r,g,b,a;
|
||||
for (int y=h;--y>=0;) {
|
||||
for (int x=0;x<w;x+=4) {
|
||||
// Read pixels
|
||||
|
@ -231,16 +232,21 @@ wxImage PRSSubtitleFormat::CalculateAlpha(const unsigned char* frame1, const uns
|
|||
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
|
||||
wxImage img(w/4,h,data,false);
|
||||
img.SetAlpha(alpha,false);
|
||||
|
||||
// Return subimage
|
||||
minx /= 4;
|
||||
maxx /= 4;
|
||||
if (dstx) *dstx = minx;
|
||||
if (dsty) *dsty = miny;
|
||||
wxImage subimg = SubImageWithAlpha(img,wxRect(minx,miny,maxx-minx+1,maxy-miny+1));
|
||||
wxImage subimg = SubImageWithAlpha(img,wxRect(minx,miny,width,height));
|
||||
return subimg;
|
||||
}
|
||||
|
||||
|
|
|
@ -61,43 +61,64 @@ PRSDisplay::~PRSDisplay() {
|
|||
|
||||
//////////////
|
||||
// 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
|
||||
fwrite("DSP",1,4,fp);
|
||||
char str[] = "DSP";
|
||||
memcpy(&vec[pos],str,4);
|
||||
pos += 4;
|
||||
|
||||
// Write block length
|
||||
unsigned __int32 utemp = 4 + 4 + 4 + 2 + 2 + 2 + 1 + 1;
|
||||
fwrite(&utemp,4,1,fp);
|
||||
memcpy(&vec[pos],&utemp,4);
|
||||
pos += 4;
|
||||
|
||||
// Write start time
|
||||
utemp = start;
|
||||
fwrite(&utemp,4,1,fp);
|
||||
memcpy(&vec[pos],&utemp,4);
|
||||
pos += 4;
|
||||
|
||||
// Write end time
|
||||
utemp = end;
|
||||
fwrite(&utemp,4,1,fp);
|
||||
memcpy(&vec[pos],&utemp,4);
|
||||
pos += 4;
|
||||
|
||||
// Write image identifier
|
||||
utemp = id;
|
||||
fwrite(&utemp,4,1,fp);
|
||||
memcpy(&vec[pos],&utemp,4);
|
||||
pos += 4;
|
||||
|
||||
// Write layer
|
||||
__int16 shorttemp = layer;
|
||||
fwrite(&shorttemp,2,1,fp);
|
||||
memcpy(&vec[pos],&shorttemp,2);
|
||||
pos += 2;
|
||||
|
||||
// Write x
|
||||
shorttemp = x;
|
||||
fwrite(&shorttemp,2,1,fp);
|
||||
memcpy(&vec[pos],&shorttemp,2);
|
||||
pos += 2;
|
||||
|
||||
// Write y
|
||||
shorttemp = y;
|
||||
fwrite(&shorttemp,2,1,fp);
|
||||
memcpy(&vec[pos],&shorttemp,2);
|
||||
pos += 2;
|
||||
|
||||
// Write alpha multiplier
|
||||
unsigned __int8 chartemp = alpha;
|
||||
fwrite(&chartemp,1,1,fp);
|
||||
memcpy(&vec[pos],&chartemp,1);
|
||||
pos += 1;
|
||||
|
||||
// Write blend mode
|
||||
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
|
||||
#include "prs_entry.h"
|
||||
#include <vector>
|
||||
|
||||
|
||||
/////////////////
|
||||
|
@ -69,5 +70,6 @@ public:
|
|||
~PRSDisplay();
|
||||
|
||||
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
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
|
||||
|
||||
//////////////
|
||||
|
@ -65,7 +66,7 @@ public:
|
|||
virtual ~PRSEntry() {}
|
||||
|
||||
virtual PRSEntryType GetType() { return BASE_ENTRY; }
|
||||
virtual void WriteData(FILE *fp) { }
|
||||
virtual void WriteData(std::vector<char> &vec) { }
|
||||
|
||||
static PRSImage* GetImage(PRSEntry* entry);
|
||||
static PRSDisplay* GetDisplay(PRSDisplay* entry);
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
///////////
|
||||
// Headers
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
#include "prs_file.h"
|
||||
#include "prs_entry.h"
|
||||
#include "prs_image.h"
|
||||
|
@ -85,7 +86,7 @@ void PRSFile::Save(std::string path) {
|
|||
fwrite("PRS",1,4,fp);
|
||||
|
||||
// Write version number (4 bytes)
|
||||
__int32 temp = 1;
|
||||
unsigned __int32 temp = 1;
|
||||
fwrite(&temp,4,1,fp);
|
||||
|
||||
// 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);
|
||||
|
||||
// Write data blocks
|
||||
std::vector<char> vec;
|
||||
std::list<PRSEntry*>::iterator cur;
|
||||
for (cur=entryList.begin();cur!=entryList.end();cur++) {
|
||||
// Data blocks take care of writing themselves
|
||||
// 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
|
||||
(*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
|
||||
fclose(fp);
|
||||
|
@ -113,6 +122,85 @@ void PRSFile::Save(std::string path) {
|
|||
////////
|
||||
// Load
|
||||
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
|
||||
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
|
||||
fwrite("IMG",1,4,fp);
|
||||
char str[] = "IMG";
|
||||
memcpy(&vec[pos],str,4);
|
||||
pos += 4;
|
||||
|
||||
// Write block length
|
||||
unsigned __int32 utemp = 4 + 4 + 4 + dataLen;
|
||||
fwrite(&utemp,4,1,fp);
|
||||
memcpy(&vec[pos],&utemp,4);
|
||||
pos += 4;
|
||||
|
||||
// Write image identifier
|
||||
utemp = id;
|
||||
fwrite(&utemp,4,1,fp);
|
||||
memcpy(&vec[pos],&utemp,4);
|
||||
pos += 4;
|
||||
|
||||
// Write image format
|
||||
utemp = imageType;
|
||||
fwrite(&utemp,4,1,fp);
|
||||
memcpy(&vec[pos],&utemp,4);
|
||||
pos += 4;
|
||||
|
||||
// Write data length
|
||||
utemp = dataLen;
|
||||
fwrite(&utemp,4,1,fp);
|
||||
memcpy(&vec[pos],&utemp,4);
|
||||
pos += 4;
|
||||
|
||||
// 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
|
||||
#include "prs_entry.h"
|
||||
#include <vector>
|
||||
|
||||
|
||||
///////////////
|
||||
|
@ -65,5 +66,6 @@ public:
|
|||
~PRSImage();
|
||||
|
||||
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