Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tpixelutils.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
enum { SUBSTITUTE,
Toshihiro Shimizu 890ddd
	   PATTERNTYPE,
Toshihiro Shimizu 890ddd
	   ADD,
Toshihiro Shimizu 890ddd
	   SUBTRACT,
Toshihiro Shimizu 890ddd
	   MULTIPLY,
Toshihiro Shimizu 890ddd
	   LIGHTEN,
Toshihiro Shimizu 890ddd
	   DARKEN };
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
typedef void (*func32)(TPixel32 &pixmask, const TPixel32 &pixtext, double v);
Toshihiro Shimizu 890ddd
typedef void (*func64)(TPixel64 &pixmask, const TPixel64 &pixtext, double v);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=======================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//  Pixel operations
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//!Make \b pixout completely opaque if \b pixcomp is not fully transparent. This helps
Toshihiro Shimizu 890ddd
//!in avoiding antialias merge problems when overing palette filtered masks with their
Toshihiro Shimizu 890ddd
//!inverses.
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
inline void makeOpaque(T &pixout, const T &pixcomp, double v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (pixcomp.m > 0) {
Toshihiro Shimizu 890ddd
		double k = T::maxChannelValue / (double)pixout.m;
Toshihiro Shimizu 890ddd
		pixout.r = troundp(k * pixout.r);
Toshihiro Shimizu 890ddd
		pixout.g = troundp(k * pixout.g);
Toshihiro Shimizu 890ddd
		pixout.b = troundp(k * pixout.b);
Toshihiro Shimizu 890ddd
		pixout.m = T::maxChannelValue;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//!Copies \b pixin into \b pixout - while matte components are multiplied.
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
inline void substitute(T &pixout, const T &pixin, double v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double k = pixout.m / (double)T::maxChannelValue;
Toshihiro Shimizu 890ddd
	pixout.r = k * pixin.r;
Toshihiro Shimizu 890ddd
	pixout.g = k * pixin.g;
Toshihiro Shimizu 890ddd
	pixout.b = k * pixin.b;
Toshihiro Shimizu 890ddd
	pixout.m = k * pixin.m;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//!Decrease \b pixout's rgb colors proportionally to \b pixin's value. The matte channel
Toshihiro Shimizu 890ddd
//!is kept unaltered.
Toshihiro Shimizu 890ddd
inline void pattern32(TPixel32 &pixout, const TPixel32 &pixin, double v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double val = TPixelGR8::from(pixin).value / 255.0;
Toshihiro Shimizu 890ddd
	pixout.r = troundp(val * pixout.r);
Toshihiro Shimizu 890ddd
	pixout.g = troundp(val * pixout.g);
Toshihiro Shimizu 890ddd
	pixout.b = troundp(val * pixout.b);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline void pattern64(TPixel64 &pixout, const TPixel64 &pixin, double v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double val = TPixelGR16::from(pixin).value / 65535.0;
Toshihiro Shimizu 890ddd
	pixout.r = troundp(val * pixout.r);
Toshihiro Shimizu 890ddd
	pixout.g = troundp(val * pixout.g);
Toshihiro Shimizu 890ddd
	pixout.b = troundp(val * pixout.b);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
void textureAdd(T &pixout, const T &pixin, double v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (pixin.m > 0) {
Toshihiro Shimizu 890ddd
		TINT32 pixoutm = pixout.m;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		double k = T::maxChannelValue / (double)pixoutm;
Toshihiro Shimizu 890ddd
		pixout.r = pixout.r * k;
Toshihiro Shimizu 890ddd
		pixout.g = pixout.g * k;
Toshihiro Shimizu 890ddd
		pixout.b = pixout.b * k;
Toshihiro Shimizu 890ddd
		pixout.m = T::maxChannelValue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		add(pixout, pixin, v);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		k = pixoutm / (double)T::maxChannelValue;
Toshihiro Shimizu 890ddd
		pixout.r = pixout.r * k;
Toshihiro Shimizu 890ddd
		pixout.g = pixout.g * k;
Toshihiro Shimizu 890ddd
		pixout.b = pixout.b * k;
Toshihiro Shimizu 890ddd
		pixout.m = pixoutm;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
void textureSub(T &pixout, const T &pixin, double v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (pixin.m > 0) {
Toshihiro Shimizu 890ddd
		TINT32 pixoutm = pixout.m;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		double k = T::maxChannelValue / (double)pixoutm;
Toshihiro Shimizu 890ddd
		pixout.r = pixout.r * k;
Toshihiro Shimizu 890ddd
		pixout.g = pixout.g * k;
Toshihiro Shimizu 890ddd
		pixout.b = pixout.b * k;
Toshihiro Shimizu 890ddd
		pixout.m = T::maxChannelValue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		sub(pixout, pixin, v);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		k = pixoutm / (double)T::maxChannelValue;
Toshihiro Shimizu 890ddd
		pixout.r = pixout.r * k;
Toshihiro Shimizu 890ddd
		pixout.g = pixout.g * k;
Toshihiro Shimizu 890ddd
		pixout.b = pixout.b * k;
Toshihiro Shimizu 890ddd
		pixout.m = pixoutm;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
void textureMult(T &pixout, const T &pixin, double v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TINT32 pixoutm = pixout.m;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double k = T::maxChannelValue / (double)pixoutm;
Toshihiro Shimizu 890ddd
	pixout.r = pixout.r * k;
Toshihiro Shimizu 890ddd
	pixout.g = pixout.g * k;
Toshihiro Shimizu 890ddd
	pixout.b = pixout.b * k;
Toshihiro Shimizu 890ddd
	pixout.m = T::maxChannelValue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	mult(pixout, pixin, v);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	k = pixoutm / (double)T::maxChannelValue;
Toshihiro Shimizu 890ddd
	pixout.r = pixout.r * k;
Toshihiro Shimizu 890ddd
	pixout.g = pixout.g * k;
Toshihiro Shimizu 890ddd
	pixout.b = pixout.b * k;
Toshihiro Shimizu 890ddd
	pixout.m = pixoutm;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
void textureLighten(T &pixout, const T &pixin, double v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TINT32 pixoutm = pixout.m;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double k = T::maxChannelValue / (double)pixoutm;
Toshihiro Shimizu 890ddd
	pixout.r = pixout.r * k;
Toshihiro Shimizu 890ddd
	pixout.g = pixout.g * k;
Toshihiro Shimizu 890ddd
	pixout.b = pixout.b * k;
Toshihiro Shimizu 890ddd
	pixout.m = T::maxChannelValue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	lighten(pixout, pixin, v);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	k = pixoutm / (double)T::maxChannelValue;
Toshihiro Shimizu 890ddd
	pixout.r = pixout.r * k;
Toshihiro Shimizu 890ddd
	pixout.g = pixout.g * k;
Toshihiro Shimizu 890ddd
	pixout.b = pixout.b * k;
Toshihiro Shimizu 890ddd
	pixout.m = pixoutm;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
void textureDarken(T &pixout, const T &pixin, double v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TINT32 pixoutm = pixout.m;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double k = T::maxChannelValue / (double)pixoutm;
Toshihiro Shimizu 890ddd
	pixout.r = pixout.r * k;
Toshihiro Shimizu 890ddd
	pixout.g = pixout.g * k;
Toshihiro Shimizu 890ddd
	pixout.b = pixout.b * k;
Toshihiro Shimizu 890ddd
	pixout.m = T::maxChannelValue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	darken(pixout, pixin, v);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	k = pixoutm / (double)T::maxChannelValue;
Toshihiro Shimizu 890ddd
	pixout.r = pixout.r * k;
Toshihiro Shimizu 890ddd
	pixout.g = pixout.g * k;
Toshihiro Shimizu 890ddd
	pixout.b = pixout.b * k;
Toshihiro Shimizu 890ddd
	pixout.m = pixoutm;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=======================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void myOver32(const TRaster32P &rasOut, const TRasterP &rasUp,
Toshihiro Shimizu 890ddd
			  func32 func, double v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(rasOut->getSize() == rasUp->getSize());
Toshihiro Shimizu 890ddd
	TRaster32P rasUp32 = rasUp;
Toshihiro Shimizu 890ddd
	assert(rasUp32);
Toshihiro Shimizu 890ddd
	for (int y = rasOut->getLy(); --y >= 0;) {
Toshihiro Shimizu 890ddd
		TPixel32 *out_pix = rasOut->pixels(y);
Toshihiro Shimizu 890ddd
		TPixel32 *const out_end = out_pix + rasOut->getLx();
Toshihiro Shimizu 890ddd
		const TPixel32 *up_pix = rasUp32->pixels(y);
Toshihiro Shimizu 890ddd
		for (; out_pix < out_end; ++out_pix, ++up_pix) {
Toshihiro Shimizu 890ddd
			if (out_pix->m > 0)
Toshihiro Shimizu 890ddd
				(*func)(*out_pix, *up_pix, v);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void myOver64(const TRaster64P &rasOut, const TRasterP &rasUp,
Toshihiro Shimizu 890ddd
			  func64 func, double v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(rasOut->getSize() == rasUp->getSize());
Toshihiro Shimizu 890ddd
	TRaster64P rasUp64 = rasUp;
Toshihiro Shimizu 890ddd
	assert(rasUp64);
Toshihiro Shimizu 890ddd
	for (int y = rasOut->getLy(); --y >= 0;) {
Toshihiro Shimizu 890ddd
		TPixel64 *out_pix = rasOut->pixels(y);
Toshihiro Shimizu 890ddd
		TPixel64 *const out_end = out_pix + rasOut->getLx();
Toshihiro Shimizu 890ddd
		const TPixel64 *up_pix = rasUp64->pixels(y);
Toshihiro Shimizu 890ddd
		for (; out_pix < out_end; ++out_pix, ++up_pix) {
Toshihiro Shimizu 890ddd
			if (out_pix->m > 0)
Toshihiro Shimizu 890ddd
				(*func)(*out_pix, *up_pix, v);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}