diff --git a/prs/png_wrap.cpp b/prs/png_wrap.cpp new file mode 100644 index 000000000..95adf87c8 --- /dev/null +++ b/prs/png_wrap.cpp @@ -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 +#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; +} diff --git a/prs/png_wrap.h b/prs/png_wrap.h new file mode 100644 index 000000000..2d0854caa --- /dev/null +++ b/prs/png_wrap.h @@ -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); +}; diff --git a/prs/prs_file.cpp b/prs/prs_file.cpp index c474fb0bc..8e40ccc0f 100644 --- a/prs/prs_file.cpp +++ b/prs/prs_file.cpp @@ -38,6 +38,7 @@ // Headers #include #include +#include #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;iid); + + // 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 &blocks) { + // Find all blocks that match + std::list::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::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; +} + diff --git a/prs/prs_file.h b/prs/prs_file.h index 2cef49bde..96a16e505 100644 --- a/prs/prs_file.h +++ b/prs/prs_file.h @@ -69,6 +69,7 @@ public: void GetDisplayBlocksAtFrame(int n,std::vector &blocks); void DrawFrame(int n,PRSVideoFrame *frame); + PRSImage *GetImageByID(int id); PRSImage *FindDuplicateImage(PRSImage *img); }; diff --git a/prs/prs_image.cpp b/prs/prs_image.cpp index a985acf64..92b75cdf7 100644 --- a/prs/prs_image.cpp +++ b/prs/prs_image.cpp @@ -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 &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; +} diff --git a/prs/prs_image.h b/prs/prs_image.h index 5a88234f6..b71ae48f3 100644 --- a/prs/prs_image.h +++ b/prs/prs_image.h @@ -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 &vec); void ReadData(std::vector &vec); diff --git a/prs/prs_video_frame.cpp b/prs/prs_video_frame.cpp index 5b8c743fa..8d46d842c 100644 --- a/prs/prs_video_frame.cpp +++ b/prs/prs_video_frame.cpp @@ -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) { +} diff --git a/prs/prs_video_frame.h b/prs/prs_video_frame.h index c6bfc99bf..f29a9ae9c 100644 --- a/prs/prs_video_frame.h +++ b/prs/prs_video_frame.h @@ -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); };