From 065056157c085c1f83897741139455b492ec4392 Mon Sep 17 00:00:00 2001
From: Rodrigo Braz Monteiro <zeratul@cellosoft.com>
Date: Sat, 1 Apr 2006 11:00:55 +0000
Subject: [PATCH] Finished PNG loading, but totally untested

Originally committed to SVN as r274.
---
 prs/png_wrap.cpp  | 52 ++++++++++++++++++++++++++++++++++++-----------
 prs/png_wrap.h    | 15 +++++++++++++-
 prs/prs_image.cpp |  2 +-
 3 files changed, 55 insertions(+), 14 deletions(-)

diff --git a/prs/png_wrap.cpp b/prs/png_wrap.cpp
index 95adf87c8..7344d1b37 100644
--- a/prs/png_wrap.cpp
+++ b/prs/png_wrap.cpp
@@ -38,6 +38,7 @@
 // Headers
 #include <png.h>
 #include "png_wrap.h"
+#include "prs_video_frame.h"
 
 
 ///////////////
@@ -57,18 +58,9 @@ PNGWrapper::~PNGWrapper() {
 
 //////////////
 // Read image
-void PNGWrapper::Read(void *dst) {
-	// Check initialization
-	if (!initialized) Begin();
-}
-
-
-//////////////
-// Initialize
-void PNGWrapper::Begin() {
-	// Check initialization
-	if (initialized) End();
-	initialized = true;
+void PNGWrapper::Read(PRSVideoFrame *frame) {
+	// Begin
+	Begin();
 
 	// Initialize libpng structures
 	png_structp png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
@@ -90,6 +82,29 @@ void PNGWrapper::Begin() {
 		throw 1;
 	}
 
+	// Set data reading
+	png_set_read_fn(png_ptr,this,memory_read_data);
+
+	// Set row pointers
+	png_bytepp row_pointers = (png_bytep *) png_malloc(png_ptr, frame->h*sizeof(png_bytep));
+	for (int i=0; i<frame->h; i++) row_pointers[i] = (png_bytep) (frame->data[0] + frame->w*i);
+	png_set_rows(png_ptr, info_ptr, row_pointers);
+
+	// Read data
+	png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
+
+	// Clean up
+	png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
+	End();
+}
+
+
+//////////////
+// Initialize
+void PNGWrapper::Begin() {
+	// Check initialization
+	if (initialized) End();
+	initialized = true;
 }
 
 
@@ -100,3 +115,16 @@ void PNGWrapper::End() {
 	if (!initialized) return;
 	initialized = false;
 }
+
+
+/////////////
+// Read data
+void PNGWrapper::memory_read_data(png_structp png_ptr, png_bytep dstData, png_size_t length) {
+	PNGWrapper *wrapper = (PNGWrapper*) png_get_io_ptr(png_ptr);
+	wrapper->ReadData(dstData,length);
+}
+
+void PNGWrapper::ReadData(png_bytep dstData, png_size_t length) {
+	memcpy(dstData,((char*)data)+pos,length);
+	pos++;
+}
diff --git a/prs/png_wrap.h b/prs/png_wrap.h
index 2d0854caa..95814ee60 100644
--- a/prs/png_wrap.h
+++ b/prs/png_wrap.h
@@ -34,6 +34,16 @@
 //
 
 
+///////////
+// Headers
+#include <png.h>
+
+
+//////////////
+// Prototypes
+class PRSVideoFrame;
+
+
 /////////////////////
 // PNG Wrapper class
 class PNGWrapper {
@@ -45,6 +55,9 @@ private:
 	void Begin();
 	void End();
 
+	static void memory_read_data(png_structp png_ptr, png_bytep data, png_size_t length);
+	void ReadData(png_bytep data, png_size_t length);
+
 public:
 	PNGWrapper();
 	~PNGWrapper();
@@ -52,5 +65,5 @@ public:
 	void SetData(void *ptr) { data = ptr; pos = 0; }
 	void *GetData() { return data; }
 
-	void Read(void *dst);
+	void Read(PRSVideoFrame *dst);
 };
diff --git a/prs/prs_image.cpp b/prs/prs_image.cpp
index 92b75cdf7..ac6d1e458 100644
--- a/prs/prs_image.cpp
+++ b/prs/prs_image.cpp
@@ -139,7 +139,7 @@ PRSVideoFrame *PRSImage::GetDecodedFrame() {
 	try {
 		PNGWrapper png;
 		png.SetData(data);
-		png.Read(frame->data[0]);
+		png.Read(frame);
 	}
 	
 	// Handle errors