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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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