Some more work on decoder
Originally committed to SVN as r273.
This commit is contained in:
parent
b83fa462e9
commit
121c81a157
8 changed files with 280 additions and 6 deletions
102
prs/png_wrap.cpp
Normal file
102
prs/png_wrap.cpp
Normal 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
56
prs/png_wrap.h
Normal 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);
|
||||||
|
};
|
|
@ -38,6 +38,7 @@
|
||||||
// Headers
|
// Headers
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
#include "prs_file.h"
|
#include "prs_file.h"
|
||||||
#include "prs_entry.h"
|
#include "prs_entry.h"
|
||||||
#include "prs_image.h"
|
#include "prs_image.h"
|
||||||
|
@ -247,9 +248,20 @@ void PRSFile::DrawFrame(int n,PRSVideoFrame *frame) {
|
||||||
GetDisplayBlocksAtFrame(n,blocks);
|
GetDisplayBlocksAtFrame(n,blocks);
|
||||||
|
|
||||||
// Draw the blocks
|
// Draw the blocks
|
||||||
int nblocks = blocks.size();
|
int nblocks = (int) blocks.size();
|
||||||
for (int i=0;i<nblocks;i++) {
|
for (int i=0;i<nblocks;i++) {
|
||||||
|
// Get display and image pair
|
||||||
PRSDisplay *display = blocks[i];
|
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
|
// Finds which display blocks are at a position
|
||||||
void PRSFile::GetDisplayBlocksAtFrame(int n,std::vector<PRSDisplay*> &blocks) {
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,7 @@ public:
|
||||||
|
|
||||||
void GetDisplayBlocksAtFrame(int n,std::vector<PRSDisplay*> &blocks);
|
void GetDisplayBlocksAtFrame(int n,std::vector<PRSDisplay*> &blocks);
|
||||||
void DrawFrame(int n,PRSVideoFrame *frame);
|
void DrawFrame(int n,PRSVideoFrame *frame);
|
||||||
|
PRSImage *GetImageByID(int id);
|
||||||
|
|
||||||
PRSImage *FindDuplicateImage(PRSImage *img);
|
PRSImage *FindDuplicateImage(PRSImage *img);
|
||||||
};
|
};
|
||||||
|
|
|
@ -36,7 +36,9 @@
|
||||||
|
|
||||||
///////////
|
///////////
|
||||||
// Headers
|
// Headers
|
||||||
|
#include "png_wrap.h"
|
||||||
#include "prs_image.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);
|
memcpy(data,&vec[pos],dataLen);
|
||||||
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;
|
||||||
|
}
|
||||||
|
|
|
@ -53,6 +53,11 @@ enum PRSImageType {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//////////////
|
||||||
|
// Prototypes
|
||||||
|
class PRSVideoFrame;
|
||||||
|
|
||||||
|
|
||||||
///////////////
|
///////////////
|
||||||
// Image class
|
// Image class
|
||||||
class PRSImage : public PRSEntry {
|
class PRSImage : public PRSEntry {
|
||||||
|
@ -70,6 +75,8 @@ public:
|
||||||
PRSImage();
|
PRSImage();
|
||||||
~PRSImage();
|
~PRSImage();
|
||||||
|
|
||||||
|
PRSVideoFrame *GetDecodedFrame();
|
||||||
|
|
||||||
PRSEntryType GetType() { return IMAGE_ENTRY; }
|
PRSEntryType GetType() { return IMAGE_ENTRY; }
|
||||||
void WriteData(std::vector<char> &vec);
|
void WriteData(std::vector<char> &vec);
|
||||||
void ReadData(std::vector<char> &vec);
|
void ReadData(std::vector<char> &vec);
|
||||||
|
|
|
@ -32,3 +32,33 @@
|
||||||
// Website: http://aegisub.cellosoft.com
|
// Website: http://aegisub.cellosoft.com
|
||||||
// Contact: mailto:zeratul@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) {
|
||||||
|
}
|
||||||
|
|
|
@ -50,9 +50,15 @@ enum ColorSpaceType {
|
||||||
// Video frame class
|
// Video frame class
|
||||||
class PRSVideoFrame {
|
class PRSVideoFrame {
|
||||||
public:
|
public:
|
||||||
char *data[4];
|
bool ownData; // If set to true, data will be deleted on destructor (defaults to false)
|
||||||
int w;
|
char *data[4]; // Data for each of the planes (interleaved formats only use data[0])
|
||||||
int h;
|
int w; // Width
|
||||||
int pitch;
|
int h; // Height
|
||||||
ColorSpaceType colorSpace;
|
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);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue