Untested PRS loading implemented (still doesn't parse data blocks, though)

Originally committed to SVN as r260.
This commit is contained in:
Rodrigo Braz Monteiro 2006-03-30 10:00:56 +00:00
parent 5682ca97b4
commit 68cd073396
7 changed files with 172 additions and 35 deletions

View File

@ -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;
}

View File

@ -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) {
}

View File

@ -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);
};

View File

@ -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);

View File

@ -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);
}

View File

@ -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) {
}

View File

@ -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);
};