Blame synfig-core/src/synfig/rendering/software/function/packedsurface.h

1febca
/* === S Y N F I G ========================================================= */
1febca
/*!	\file synfig/rendering/software/function/packedsurface.h
1febca
**	\brief PackedSurface Header
1febca
**
1febca
**	$Id$
1febca
**
1febca
**	\legal
1febca
**	......... ... 2016 Ivan Mahonin
1febca
**
1febca
**	This package is free software; you can redistribute it and/or
1febca
**	modify it under the terms of the GNU General Public License as
1febca
**	published by the Free Software Foundation; either version 2 of
1febca
**	the License, or (at your option) any later version.
1febca
**
1febca
**	This package is distributed in the hope that it will be useful,
1febca
**	but WITHOUT ANY WARRANTY; without even the implied warranty of
1febca
**	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1febca
**	General Public License for more details.
1febca
**	\endlegal
1febca
*/
1febca
/* ========================================================================= */
1febca
1febca
/* === S T A R T =========================================================== */
1febca
1febca
#ifndef __SYNFIG_RENDERING_SOFTWARE_PACKEDSURFACE_H
1febca
#define __SYNFIG_RENDERING_SOFTWARE_PACKEDSURFACE_H
1febca
1febca
/* === H E A D E R S ======================================================= */
1febca
1febca
#include <set></set>
1febca
1febca
#include <synfig real.h=""></synfig>
1febca
#include <synfig color.h=""></synfig>
1febca
#include <synfig surface.h=""></synfig>
1febca
1febca
#include "../../primitive/contour.h"
1febca
#include "../../primitive/polyspan.h"
1febca
1febca
/* === M A C R O S ========================================================= */
1febca
1febca
/* === T Y P E D E F S ===================================================== */
1febca
1febca
/* === C L A S S E S & S T R U C T S ======================================= */
1febca
1febca
namespace synfig
1febca
{
1febca
namespace rendering
1febca
{
1febca
namespace software
1febca
{
1febca
1febca
class PackedSurface
1febca
{
1febca
public:
1febca
	enum ChannelType {
1febca
		ChannelUInt8,
1febca
		ChannelFloat32
1febca
	};
1febca
1febca
	enum {
1febca
		ChunkSize = 32,
1febca
		CacheRows = 2
1febca
	};
1febca
1febca
	class Reader
1febca
	{
1febca
	private:
1febca
		struct CacheEntry {
1febca
			int chunk_index;
1febca
			CacheEntry *prev;
1febca
			CacheEntry *next;
1febca
			void *data(int offset = 0) { return (char*)this + sizeof(*this) + offset; }
1febca
		};
1febca
1febca
		const PackedSurface *surface;
1febca
		mutable CacheEntry* first;
1febca
		mutable CacheEntry* last;
1febca
		mutable std::vector<cacheentry*> chunks;</cacheentry*>
1febca
		char* cache;
1febca
1febca
	public:
1febca
1febca
		Reader();
1febca
		explicit Reader(const PackedSurface &surface);
1febca
		~Reader();
1febca
1febca
		void open(const PackedSurface &surface);
1febca
		void close();
1febca
		bool is_opened() const { return surface != NULL; }
1febca
1febca
		Color get_pixel(int x, int y) const;
1febca
a9a619
		template< etl::clamping::func clamp_x = etl::clamping::clamp,
a9a619
				  etl::clamping::func clamp_y = etl::clamping::clamp >
1febca
		inline static Color reader(const void *surf, int x, int y)
17812b
		{
17812b
			const Reader &r = *(const Reader*)surf;
17812b
			return clamp_x(x, r.surface->width) && clamp_y(y, r.surface->height)
17812b
			     ? r.get_pixel(x, y) : Color();
17812b
		}
17812b
a9a619
		template< etl::clamping::func clamp_x = etl::clamping::clamp,
a9a619
				  etl::clamping::func clamp_y = etl::clamping::clamp >
1febca
		inline static ColorAccumulator reader_cook(const void *surf, int x, int y)
17812b
		{
17812b
			const Reader &r = *(const Reader*)surf;
17812b
			return clamp_x(x, r.surface->width) && clamp_y(y, r.surface->height)
17812b
				 ? ColorPrep::cook_static(r.get_pixel(x, y)) : Color();
17812b
		}
1febca
	};
1febca
1febca
	struct DiscreteHelper {
1febca
		Color::value_type value;
1febca
		Color::value_type min;
1febca
		Color::value_type max;
1febca
		int count;
1febca
		DiscreteHelper(): value(), min(), max(), count() { }
1febca
		DiscreteHelper(Color::value_type c):
1febca
			value(c),
1febca
			min(c - real_low_precision<color::value_type>()),</color::value_type>
1febca
			max(c + real_low_precision<color::value_type>()),</color::value_type>
1febca
			count(1)
1febca
		{ }
1febca
		bool in_range(Color::value_type c) const
1febca
			{ return min <= c && c <= max; }
1febca
	};
1febca
62f661
	typedef etl::sampler<coloraccumulator, coloraccumulator,="" float,="" reader::reader_cook=""> Sampler;</coloraccumulator,>
62f661
1febca
private:
Rodolfo Ribeiro Gomes cfe072
	mutable std::mutex mutex;
1febca
	mutable std::set<reader*> readers;</reader*>
1febca
1febca
	int width;
1febca
	int height;
1febca
1febca
	ChannelType channel_type;
1febca
	int channels[4];
1febca
	Color::value_type discrete_to_float[256];
1febca
	Color constant;
1febca
1febca
	int pixel_size;
1febca
	int row_size;
1febca
1febca
	int chunk_size;
1febca
	int chunk_row_size;
1febca
	int chunks_width;
1febca
	int chunks_height;
1febca
1febca
	std::vector<char> data;</char>
1febca
1febca
	static Color::value_type get_channel(const void *pixel, int offset, ChannelType type, Color::value_type constant, const Color::value_type *discrete_to_float);
1febca
	static void set_channel(void *pixel, int offset, ChannelType type, Color::value_type color, const Color::value_type *discrete_to_float);
1febca
1febca
	Color get_pixel(const void *pixel) const;
1febca
	void set_pixel(void *pixel, const Color &color);
1febca
1febca
	void get_compressed_chunk(int index, const void *&data, int &size, bool &compressed) const;
1febca
1febca
public:
1febca
	PackedSurface();
1febca
	~PackedSurface();
1febca
1febca
	void clear();
1febca
	void set_pixels(const Color *pixels, int width, int height, int pitch = 0);
1febca
	int get_width() const { return width; }
1febca
	int get_height() const { return height; }
1febca
	void get_pixels(Color *target) const;
1febca
};
1febca
1febca
} /* end namespace software */
1febca
} /* end namespace rendering */
1febca
} /* end namespace synfig */
1febca
1febca
/* -- E N D ----------------------------------------------------------------- */
1febca
1febca
#endif