Some more work on decoder

Originally committed to SVN as r273.
This commit is contained in:
Rodrigo Braz Monteiro 2006-04-01 10:38:54 +00:00
parent b83fa462e9
commit 121c81a157
8 changed files with 280 additions and 6 deletions

102
prs/png_wrap.cpp Normal file
View File

@ -0,0 +1,102 @@
// Copyright (c) 2006, Rodrigo Braz Monteiro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Aegisub Group nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------------
//
// AEGISUB
//
// Website: http://aegisub.cellosoft.com
// Contact: mailto:zeratul@cellosoft.com
//
///////////
// Headers
#include <png.h>
#include "png_wrap.h"
///////////////
// Constructor
PNGWrapper::PNGWrapper() {
initialized = false;
pos = 0;
}
//////////////
// Destructor
PNGWrapper::~PNGWrapper() {
if (initialized) End();
}
//////////////
// Read image
void PNGWrapper::Read(void *dst) {
// Check initialization
if (!initialized) Begin();
}
//////////////
// Initialize
void PNGWrapper::Begin() {
// Check initialization
if (initialized) End();
initialized = true;
// Initialize libpng structures
png_structp png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr) throw 1;
png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) {
png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
throw 1;
}
png_infop end_info = png_create_info_struct(png_ptr);
if (!end_info) {
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
throw 1;
}
// Set jump for error handling (man, I hate this lib)
if (setjmp(png_jmpbuf(png_ptr))) {
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
throw 1;
}
}
////////////
// Clean up
void PNGWrapper::End() {
// Check initialization
if (!initialized) return;
initialized = false;
}

56
prs/png_wrap.h Normal file
View File

@ -0,0 +1,56 @@
// Copyright (c) 2006, Rodrigo Braz Monteiro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Aegisub Group nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------------
//
// AEGISUB
//
// Website: http://aegisub.cellosoft.com
// Contact: mailto:zeratul@cellosoft.com
//
/////////////////////
// PNG Wrapper class
class PNGWrapper {
private:
bool initialized;
int pos;
void *data;
void Begin();
void End();
public:
PNGWrapper();
~PNGWrapper();
void SetData(void *ptr) { data = ptr; pos = 0; }
void *GetData() { return data; }
void Read(void *dst);
};

View File

@ -38,6 +38,7 @@
// Headers
#include <stdio.h>
#include <vector>
#include <algorithm>
#include "prs_file.h"
#include "prs_entry.h"
#include "prs_image.h"
@ -247,9 +248,20 @@ void PRSFile::DrawFrame(int n,PRSVideoFrame *frame) {
GetDisplayBlocksAtFrame(n,blocks);
// Draw the blocks
int nblocks = blocks.size();
int nblocks = (int) blocks.size();
for (int i=0;i<nblocks;i++) {
// Get display and image pair
PRSDisplay *display = blocks[i];
PRSImage *image = GetImageByID(display->id);
// Decode PNG
PRSVideoFrame *overFrame = image->GetDecodedFrame();
// Draw image on frame
// TODO
// Clean up
delete overFrame;
}
}
@ -257,4 +269,31 @@ void PRSFile::DrawFrame(int n,PRSVideoFrame *frame) {
////////////////////////////////////////////////
// Finds which display blocks are at a position
void PRSFile::GetDisplayBlocksAtFrame(int n,std::vector<PRSDisplay*> &blocks) {
// Find all blocks that match
std::list<PRSEntry*>::iterator cur;
PRSDisplay *display;
for (cur=entryList.begin();cur!=entryList.end();cur++) {
display = PRSEntry::GetDisplay(*cur);
if (display) blocks.push_back(display);
}
// Sort them by layer
// TODO
}
///////////////////////////////////////////////////////////////
// Gets a PRSImage by its ID, returns NULL if it doesn't exist
PRSImage *PRSFile::GetImageByID(int id) {
// Search for image
std::list<PRSEntry*>::iterator cur;
PRSImage *img;
for (cur=entryList.begin();cur!=entryList.end();cur++) {
img = PRSEntry::GetImage(*cur);
if (img && img->id == id) return img;
}
// Not found
return NULL;
}

View File

@ -69,6 +69,7 @@ public:
void GetDisplayBlocksAtFrame(int n,std::vector<PRSDisplay*> &blocks);
void DrawFrame(int n,PRSVideoFrame *frame);
PRSImage *GetImageByID(int id);
PRSImage *FindDuplicateImage(PRSImage *img);
};

View File

@ -36,7 +36,9 @@
///////////
// Headers
#include "png_wrap.h"
#include "prs_image.h"
#include "prs_video_frame.h"
///////////////
@ -118,3 +120,34 @@ void PRSImage::ReadData(std::vector<char> &vec) {
memcpy(data,&vec[pos],dataLen);
pos += dataLen;
}
////////////////
// Decode frame
PRSVideoFrame *PRSImage::GetDecodedFrame() {
// Create frame
PRSVideoFrame *frame = new PRSVideoFrame;
// Allocate frame data
frame->ownData = true;
frame->data[0] = new char[w*h];
frame->w = w;
frame->h = h;
frame->pitch = w;
frame->colorSpace = ColorSpace_RGB32;
try {
PNGWrapper png;
png.SetData(data);
png.Read(frame->data[0]);
}
// Handle errors
catch (...) {
delete frame;
return NULL;
}
// Return frame
return frame;
}

View File

@ -53,6 +53,11 @@ enum PRSImageType {
};
//////////////
// Prototypes
class PRSVideoFrame;
///////////////
// Image class
class PRSImage : public PRSEntry {
@ -70,6 +75,8 @@ public:
PRSImage();
~PRSImage();
PRSVideoFrame *GetDecodedFrame();
PRSEntryType GetType() { return IMAGE_ENTRY; }
void WriteData(std::vector<char> &vec);
void ReadData(std::vector<char> &vec);

View File

@ -32,3 +32,33 @@
// Website: http://aegisub.cellosoft.com
// Contact: mailto:zeratul@cellosoft.com
//
///////////
// Headers
#include "prs_video_frame.h"
///////////////
// Constructor
PRSVideoFrame::PRSVideoFrame () {
for (int i=0;i<4;i++) data[i] = 0;
w = 0;
h = 0;
ownData = false;
}
//////////////
// Destructor
PRSVideoFrame::~PRSVideoFrame () {
if (ownData) {
for (int i=0;i<4;i++) delete [] data[i];
}
}
///////////////////////////////////
// Overlay frame on top of another
void PRSVideoFrame::Overlay(PRSVideoFrame *dst,int x,int y,unsigned char alpha) {
}

View File

@ -50,9 +50,15 @@ enum ColorSpaceType {
// Video frame class
class PRSVideoFrame {
public:
char *data[4];
int w;
int h;
int pitch;
ColorSpaceType colorSpace;
bool ownData; // If set to true, data will be deleted on destructor (defaults to false)
char *data[4]; // Data for each of the planes (interleaved formats only use data[0])
int w; // Width
int h; // Height
int pitch; // Pitch (that is, width plus invisible area for optimization)
ColorSpaceType colorSpace; // Color space
PRSVideoFrame();
~PRSVideoFrame();
void Overlay(PRSVideoFrame *dst,int x,int y,unsigned char alpha=255);
};