From 68cd073396a0041325977925d555d90e72c01db9 Mon Sep 17 00:00:00 2001 From: Rodrigo Braz Monteiro Date: Thu, 30 Mar 2006 10:00:56 +0000 Subject: [PATCH] Untested PRS loading implemented (still doesn't parse data blocks, though) Originally committed to SVN as r260. --- core/subtitle_format_prs.cpp | 24 +++++---- prs/prs_display.cpp | 45 ++++++++++++----- prs/prs_display.h | 4 +- prs/prs_entry.h | 3 +- prs/prs_file.cpp | 94 ++++++++++++++++++++++++++++++++++-- prs/prs_image.cpp | 33 ++++++++++--- prs/prs_image.h | 4 +- 7 files changed, 172 insertions(+), 35 deletions(-) diff --git a/core/subtitle_format_prs.cpp b/core/subtitle_format_prs.cpp index a64e3b956..5faa39a0d 100644 --- a/core/subtitle_format_prs.cpp +++ b/core/subtitle_format_prs.cpp @@ -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 &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 &vec) { } diff --git a/prs/prs_display.h b/prs/prs_display.h index f68112601..1f30af147 100644 --- a/prs/prs_display.h +++ b/prs/prs_display.h @@ -51,6 +51,7 @@ enum PRSBlendMode { /////////// // Headers #include "prs_entry.h" +#include ///////////////// @@ -69,5 +70,6 @@ public: ~PRSDisplay(); PRSEntryType GetType() { return DISPLAY_ENTRY; } - void WriteData(FILE *fp); + void WriteData(std::vector &vec); + void ReadData(std::vector &vec); }; diff --git a/prs/prs_entry.h b/prs/prs_entry.h index 974d224f2..d9d7ae0d8 100644 --- a/prs/prs_entry.h +++ b/prs/prs_entry.h @@ -40,6 +40,7 @@ /////////// // Headers #include +#include ////////////// @@ -65,7 +66,7 @@ public: virtual ~PRSEntry() {} virtual PRSEntryType GetType() { return BASE_ENTRY; } - virtual void WriteData(FILE *fp) { } + virtual void WriteData(std::vector &vec) { } static PRSImage* GetImage(PRSEntry* entry); static PRSDisplay* GetDisplay(PRSDisplay* entry); diff --git a/prs/prs_file.cpp b/prs/prs_file.cpp index d179f4059..ad84c36a6 100644 --- a/prs/prs_file.cpp +++ b/prs/prs_file.cpp @@ -37,6 +37,7 @@ /////////// // Headers #include +#include #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 vec; std::list::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 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); } diff --git a/prs/prs_image.cpp b/prs/prs_image.cpp index 0b1fe48ce..179b9e88f 100644 --- a/prs/prs_image.cpp +++ b/prs/prs_image.cpp @@ -62,26 +62,43 @@ PRSImage::~PRSImage() { ////////////// // Write data -void PRSImage::WriteData(FILE *fp) { +void PRSImage::WriteData(std::vector &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 &vec) { } diff --git a/prs/prs_image.h b/prs/prs_image.h index 1aafce9d9..f14dfc51a 100644 --- a/prs/prs_image.h +++ b/prs/prs_image.h @@ -40,6 +40,7 @@ /////////// // Headers #include "prs_entry.h" +#include /////////////// @@ -65,5 +66,6 @@ public: ~PRSImage(); PRSEntryType GetType() { return IMAGE_ENTRY; } - void WriteData(FILE *fp); + void WriteData(std::vector &vec); + void ReadData(std::vector &vec); };