Index: trunk/nv/gl/image.hh
===================================================================
--- trunk/nv/gl/image.hh	(revision 13)
+++ trunk/nv/gl/image.hh	(revision 13)
@@ -0,0 +1,43 @@
+// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// http://chaosforge.org/
+//
+// This file is part of NV Libraries.
+// For conditions of distribution and use, see copyright notice in nv.hh
+
+#ifndef NV_IMAGE_HH
+#define NV_IMAGE_HH
+
+#include <nv/common.hh>
+#include <glm/glm.hpp>
+
+namespace nv
+{
+	struct region
+	{
+		glm::ivec2 pos;
+		glm::ivec2 size;
+
+		region() : pos(0,0), size(0,0) {}
+		region( glm::ivec2 pos, glm::ivec2 size ) : pos(pos), size(size) {}
+	};
+
+	class image
+	{
+	public:
+		image( glm::ivec2 size, size_t depth );
+		void clear();
+		void fill( uint8 value );
+		void set_region( region r, const uint8 * data, size_t stride = 0 );
+		~image();
+		const uint8 * get_data() const { return m_data; }
+		const glm::ivec2 get_size() const { return m_size; }
+		const size_t get_depth() const { return m_depth; }
+	protected:
+		glm::ivec2 m_size;
+		size_t     m_depth;
+		uint8*     m_data;
+	};
+
+}
+
+#endif // NV_IMAGE_HH
Index: trunk/nv/gl/texture_atlas.hh
===================================================================
--- trunk/nv/gl/texture_atlas.hh	(revision 12)
+++ trunk/nv/gl/texture_atlas.hh	(revision 13)
@@ -9,4 +9,5 @@
 
 #include <nv/common.hh>
+#include <nv/gl/image.hh>
 #include <glm/glm.hpp>
 #include <vector>
@@ -15,16 +16,10 @@
 {
 
-	class texture_atlas
+	class texture_atlas : public image
 	{
 	public:
 		texture_atlas( glm::ivec2 size, size_t depth );
-		glm::ivec4 get_region( glm::ivec2 size );
-		void set_region( glm::ivec4 region, const uint8 * data, size_t stride );
+		region get_region( glm::ivec2 size );
 		void clear();
-		void fill( uint8 value );
-		~texture_atlas();
-		const uint8 * get_data() const { return m_data; }
-		const glm::ivec2 get_size() const { return m_size; }
-		const size_t get_depth() const { return m_depth; }
 		const size_t get_used() const { return m_used; }
 	protected:
@@ -32,9 +27,5 @@
 		void merge();
 	private:
-	    glm::ivec2 m_size;
-	    size_t  m_depth;
 	    size_t  m_used;
-
-	    uint8 * m_data;
 		std::vector<glm::ivec3> m_nodes;
 	};
Index: trunk/src/gl/image.cc
===================================================================
--- trunk/src/gl/image.cc	(revision 13)
+++ trunk/src/gl/image.cc	(revision 13)
@@ -0,0 +1,37 @@
+// Copyright (C) 2011 Kornel Kisielewicz
+// This file is part of NV Libraries.
+// For conditions of distribution and use, see copyright notice in nv.hh
+
+#include "nv/gl/image.hh"
+
+#include <cstring>
+
+using namespace nv;
+
+image::image( glm::ivec2 size, size_t depth )
+	: m_size( size ), m_depth( depth ), m_data( nullptr )
+{
+	m_data = new uint8[ m_size.x * m_size.y * m_depth ];
+}
+
+void image::fill( uint8 value )
+{
+	memset( m_data, value, m_size.x * m_size.y * m_depth );
+}
+
+void image::set_region( region r, const uint8 * data, size_t stride )
+{
+	if ( stride == 0 ) stride = r.size.x;
+
+    for( size_t i = 0; i < r.size.y; ++i )
+    {
+        memcpy( m_data+((r.pos.y+i)*m_size.x + r.pos.x ) * m_depth, 
+                data + (i*stride), r.size.x * m_depth );
+    }
+}
+
+image::~image()
+{
+	delete[] m_data;
+}
+
Index: trunk/src/gl/texture_atlas.cc
===================================================================
--- trunk/src/gl/texture_atlas.cc	(revision 12)
+++ trunk/src/gl/texture_atlas.cc	(revision 13)
@@ -7,17 +7,18 @@
 #include "nv/gl/texture_atlas.hh"
 
+#include "nv/logging.hh"
+
 using namespace nv;
 
 texture_atlas::texture_atlas( glm::ivec2 size, size_t depth )
-	: m_size( size ), m_depth( depth ), m_used( 0 ), m_data( nullptr )
+	: image( size, depth ), m_used( 0 )
 {
 	m_nodes.push_back( glm::ivec3( 1, 1, m_size.x - 2 ) );
-	m_data = new uint8[ m_size.x * m_size.y * m_depth ];
 	fill( 0 );
 }
 
-glm::ivec4 texture_atlas::get_region( glm::ivec2 size )
+region texture_atlas::get_region( glm::ivec2 size )
 {
-	glm::ivec4 region (0,0,size.x,size.y);
+	region r ( glm::ivec2(0,0), size );
     size_t i;
 
@@ -37,6 +38,6 @@
 				best_index = i;
 				best_width = node.z;
-				region.x = node.x;
-				region.y = y;
+				r.pos.x = node.x;
+				r.pos.y = y;
 			}
         }
@@ -45,8 +46,8 @@
 	if( best_index == -1 )
     {
-        return glm::ivec4( -1, -1, 0, 0 );
+        return region( glm::ivec2( -1, -1 ), glm::ivec2( 0, 0 ) );
     }
 
-    m_nodes.insert( m_nodes.begin() + best_index, glm::ivec3( region.x, region.y + size.y, size.x ) );
+    m_nodes.insert( m_nodes.begin() + best_index, glm::ivec3( r.pos.x, r.pos.y + size.y, size.x ) );
 
     for( size_t i = best_index+1; i < m_nodes.size(); ++i )
@@ -78,14 +79,5 @@
     merge();
     m_used += size.x * size.y;
-    return region;
-}
-
-void texture_atlas::set_region( glm::ivec4 region, const uint8 * data, size_t stride )
-{
-    for( size_t i = 0; i < region[3]; ++i )
-    {
-        memcpy( m_data+((region.y+i)*m_size.x + region.x ) * m_depth, 
-                data + (i*stride), m_size.x * m_depth );
-    }
+    return r;
 }
 
@@ -140,13 +132,2 @@
 	fill( 0 );
 }
-
-void texture_atlas::fill( uint8 value )
-{
-	memset( m_data, value, m_size.x * m_size.y * m_depth );
-}
-
-texture_atlas::~texture_atlas()
-{
-	delete[] m_data;
-}
-
