/* -----------------------------------------------------------------------------
	GSFramework
	Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
------------------------------------------------------------------------------*/


		#include "pict_io_stb/pict_stb_codec.h"
		#include "picture/pict.h"
		#include "filesystem/io_handle.h"
		#include "container/narray.h"
		#include "memory/memory.h"
		#include "log/log.h"

		#define	STBI_NO_STDIO
		#include "stb_image.h"

		using namespace GS;


//-----------------------------------------------------------------------------
static int	n_stb_read_h(void *user, char *data, int size)
{	return ((IO::Handle *)user)->Read(data, size);	}
static void	n_stb_skip_h(void *user, unsigned n)
{	((IO::Handle *)user)->Seek(n);	}
static int	n_stb_eof_h(void *user)
{	return ((IO::Handle *)user)->IsEOF() ? 1 : 0;	}
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
bool				PictureSTBCodec::Load(IO::Handle &handle, Picture &picture)
{
	handle.Rewind();

	stbi_io_callbacks cb;
	cb.read = &n_stb_read_h;
	cb.skip = &n_stb_skip_h;
	cb.eof = &n_stb_eof_h;

	/*
		Swizzle and transfer to C++ allocation.
		Watch the memory peak!...
	*/
	int comp, width, height;
	if	(char *c_data = (char *)stbi_load_from_callbacks(&cb, &handle, &width, &height, &comp, STBI_rgb_alpha))
	{
		picture.AllocAs(width, height);
		if	(char *p_data = (char *)picture.GetData())
			Memory::Copy(p_data, c_data, width * height * 4);
		stbi_image_free(c_data);
	}
	return asbool(picture.GetData());
}
//-----------------------------------------------------------------------------
