Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef T_PIXELUTILS_INCLUDED
Toshihiro Shimizu 890ddd
#define T_PIXELUTILS_INCLUDED
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tpixel.h"
Toshihiro Shimizu 890ddd
#include "tpixelgr.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#undef DVAPI
Toshihiro Shimizu 890ddd
#undef DVVAR
Toshihiro Shimizu 890ddd
#ifdef TCOLOR_EXPORTS
Toshihiro Shimizu 890ddd
#define DVAPI DV_EXPORT_API
Toshihiro Shimizu 890ddd
#define DVVAR DV_EXPORT_VAR
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#define DVAPI DV_IMPORT_API
Toshihiro Shimizu 890ddd
#define DVVAR DV_IMPORT_VAR
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*! this template function computes a linear interpolation between 
Toshihiro Shimizu 890ddd
    the color \b a and \b b according to the parameter \b t.
Toshihiro Shimizu 890ddd
    If \b t = 0, it returns \b a;
Toshihiro Shimizu 890ddd
    if \b t = 1, it returns \b b;
Toshihiro Shimizu 890ddd
    No check is performed.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
inline T blend(const T &a, const T &b, double t)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return T(
Toshihiro Shimizu 890ddd
		troundp((1 - t) * a.r + t * b.r),
Toshihiro Shimizu 890ddd
		troundp((1 - t) * a.g + t * b.g),
Toshihiro Shimizu 890ddd
		troundp((1 - t) * a.b + t * b.b),
Toshihiro Shimizu 890ddd
		troundp((1 - t) * a.m + t * b.m));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*! this template function computes a linear interpolation between 
Toshihiro Shimizu 890ddd
    the color \b a and \b b according to the ratio between \b num and \b den.
Toshihiro Shimizu 890ddd
    If \b num / \b den = 0, it returns \b a;
Toshihiro Shimizu 890ddd
    if \b num / \b den = 1, it returns \b b;
Toshihiro Shimizu 890ddd
    No check is performed. 
Toshihiro Shimizu 890ddd
    \warning \b b MUST be not zero.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
inline T blend(
Toshihiro Shimizu 890ddd
	const T &a,
Toshihiro Shimizu 890ddd
	const T &b,
Toshihiro Shimizu 890ddd
	int num, int den)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return T(
Toshihiro Shimizu 890ddd
		(int)(((den - num) * a.r + num * b.r) / den),
Toshihiro Shimizu 890ddd
		(int)(((den - num) * a.g + num * b.g) / den),
Toshihiro Shimizu 890ddd
		(int)(((den - num) * a.b + num * b.b) / den),
Toshihiro Shimizu 890ddd
		(int)(((den - num) * a.m + num * b.m) / den));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
inline T antialias(
Toshihiro Shimizu 890ddd
	const T &a,
Toshihiro Shimizu 890ddd
	int num)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return T(
Toshihiro Shimizu 890ddd
		(int)((num * a.r) / 255),
Toshihiro Shimizu 890ddd
		(int)((num * a.g) / 255),
Toshihiro Shimizu 890ddd
		(int)((num * a.b) / 255),
Toshihiro Shimizu 890ddd
		(int)((num * a.m) / 255));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*! this function combines two pixels according to their alpha channel.
Toshihiro Shimizu 890ddd
    If the \b top pixel is completely opaque the function returns it.
Toshihiro Shimizu 890ddd
    If the \b top pixel is completely transparent the function returns \b bot.
Toshihiro Shimizu 890ddd
    In the other cases a blend is performed.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class class="" q="" t,=""></class>
Toshihiro Shimizu 890ddd
DVAPI inline T overPixT(const T &bot, const T &top)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	UINT max = T::maxChannelValue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (top.m == max)
Toshihiro Shimizu 890ddd
		return top;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (top.m == 0)
Toshihiro Shimizu 890ddd
		return bot;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TUINT32 r = top.r + bot.r * (max - top.m) / max;
Toshihiro Shimizu 890ddd
	TUINT32 g = top.g + bot.g * (max - top.m) / max;
Toshihiro Shimizu 890ddd
	TUINT32 b = top.b + bot.b * (max - top.m) / max;
Toshihiro Shimizu 890ddd
	return T(
Toshihiro Shimizu 890ddd
		(r < max) ? (Q)r : (Q)max,
Toshihiro Shimizu 890ddd
		(g < max) ? (Q)g : (Q)max,
Toshihiro Shimizu 890ddd
		(b < max) ? (Q)b : (Q)max,
Toshihiro Shimizu 890ddd
		(bot.m == max) ? max : max - (max - bot.m) * (max - top.m) / max);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
template <class class="" q="" s,="" t,=""></class>
Toshihiro Shimizu 890ddd
DVAPI inline T overPixGRT(const T &bot, const S &top)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	UINT max = T::maxChannelValue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (top.value == max)
Toshihiro Shimizu 890ddd
		return T(top.value, top.value, top.value, top.value);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (top.value == 0)
Toshihiro Shimizu 890ddd
		return bot;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double aux = (max - top.value) / max;
Toshihiro Shimizu 890ddd
	TUINT32 r = (TUINT32)(top.value + bot.r * aux);
Toshihiro Shimizu 890ddd
	TUINT32 g = (TUINT32)(top.value + bot.g * aux);
Toshihiro Shimizu 890ddd
	TUINT32 b = (TUINT32)(top.value + bot.b * aux);
Toshihiro Shimizu 890ddd
	return T(
Toshihiro Shimizu 890ddd
		(r < max) ? (Q)r : (Q)max,
Toshihiro Shimizu 890ddd
		(g < max) ? (Q)g : (Q)max,
Toshihiro Shimizu 890ddd
		(b < max) ? (Q)b : (Q)max,
Toshihiro Shimizu 890ddd
		(bot.m == max) ? max : (TUINT32)(max - (max - bot.m) * aux));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
//as the other, but without if's. it's quicker if you know for sure that top.m is not 0 or 255.
Toshihiro Shimizu 890ddd
template <class class="" q="" t,=""></class>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI inline T quickOverPixT(const T &bot, const T &top)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	UINT max = T::maxChannelValue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TUINT32 r = top.r + bot.r * (max - top.m) / max;
Toshihiro Shimizu 890ddd
	TUINT32 g = top.g + bot.g * (max - top.m) / max;
Toshihiro Shimizu 890ddd
	TUINT32 b = top.b + bot.b * (max - top.m) / max;
Toshihiro Shimizu 890ddd
	return T(
Toshihiro Shimizu 890ddd
		(r < max) ? (Q)r : (Q)max,
Toshihiro Shimizu 890ddd
		(g < max) ? (Q)g : (Q)max,
Toshihiro Shimizu 890ddd
		(b < max) ? (Q)b : (Q)max,
Toshihiro Shimizu 890ddd
		(bot.m == max) ? max : max - (max - bot.m) * (max - top.m) / max);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class class="" q="" t,=""></class>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI inline T quickOverPixPremultT(const T &bot, const T &top)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	UINT max = T::maxChannelValue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TUINT32 r = (top.r * top.m + bot.r * (max - top.m)) / max;
Toshihiro Shimizu 890ddd
	TUINT32 g = (top.g * top.m + bot.g * (max - top.m)) / max;
Toshihiro Shimizu 890ddd
	TUINT32 b = (top.b * top.m + bot.b * (max - top.m)) / max;
Toshihiro Shimizu 890ddd
	return T(
Toshihiro Shimizu 890ddd
		(r < max) ? (Q)r : (Q)max,
Toshihiro Shimizu 890ddd
		(g < max) ? (Q)g : (Q)max,
Toshihiro Shimizu 890ddd
		(b < max) ? (Q)b : (Q)max,
Toshihiro Shimizu 890ddd
		(bot.m == max) ? max : max - (max - bot.m) * (max - top.m) / max);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*-- Viewer上でラスタ素材を「比較暗」合成表示する --*/
Toshihiro Shimizu 890ddd
template <class class="" q="" t,=""></class>
Toshihiro Shimizu 890ddd
DVAPI inline T quickOverPixDarkenBlendedT(const T &bot, const T &top)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	UINT max = T::maxChannelValue;
Toshihiro Shimizu 890ddd
	TUINT32 r = (top.r < bot.r) ? top.r : bot.r;
Toshihiro Shimizu 890ddd
	TUINT32 g = (top.g < bot.g) ? top.g : bot.g;
Toshihiro Shimizu 890ddd
	TUINT32 b = (top.b < bot.b) ? top.b : bot.b;
Toshihiro Shimizu 890ddd
	return T(
Toshihiro Shimizu 890ddd
		(Q)r,
Toshihiro Shimizu 890ddd
		(Q)g,
Toshihiro Shimizu 890ddd
		(Q)b,
Toshihiro Shimizu 890ddd
		max);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
template <class class="" q="" s,="" t,=""></class>
Toshihiro Shimizu 890ddd
DVAPI inline T quickOverPixGRT(const T &bot, const S &top)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	UINT max = T::maxChannelValue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double aux = (max - top.value) / max;
Toshihiro Shimizu 890ddd
	TUINT32 r = (TUINT32)(top.value + bot.r * aux);
Toshihiro Shimizu 890ddd
	TUINT32 g = (TUINT32)(top.value + bot.g * aux);
Toshihiro Shimizu 890ddd
	TUINT32 b = (TUINT32)(top.value + bot.b * aux);
Toshihiro Shimizu 890ddd
	return T(
Toshihiro Shimizu 890ddd
		(r < max) ? (Q)r : (Q)max,
Toshihiro Shimizu 890ddd
		(g < max) ? (Q)g : (Q)max,
Toshihiro Shimizu 890ddd
		(b < max) ? (Q)b : (Q)max,
Toshihiro Shimizu 890ddd
		(bot.m == max) ? max : (TUINT32)(max - (max - bot.m) * aux));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI inline TPixel32 overPix(const TPixel32 &bot, const TPixelGR8 &top)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return overPixGRT<tpixel32, tpixelgr8,="" uchar="">(bot, top);</tpixel32,>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI inline TPixel64 overPix(const TPixel64 &bot, const TPixelGR16 &top)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return overPixGRT<tpixel64, tpixelgr16,="" ushort="">(bot, top);</tpixel64,>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI inline TPixel32 overPix(const TPixel32 &bot, const TPixel32 &top)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return overPixT<tpixel32, uchar="">(bot, top);</tpixel32,>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI inline TPixel64 overPix(const TPixel64 &bot, const TPixel64 &top)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return overPixT<tpixel64, ushort="">(bot, top);</tpixel64,>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI inline TPixel32 quickOverPix(const TPixel32 &bot, const TPixelGR8 &top)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return quickOverPixGRT<tpixel32, tpixelgr8,="" uchar="">(bot, top);</tpixel32,>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI inline TPixel64 quickOverPix(const TPixel64 &bot, const TPixelGR16 &top)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return quickOverPixGRT<tpixel64, tpixelgr16,="" ushort="">(bot, top);</tpixel64,>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI inline TPixel32 quickOverPix(const TPixel32 &bot, const TPixel32 &top)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return quickOverPixT<tpixel32, uchar="">(bot, top);</tpixel32,>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI inline TPixel32 quickOverPixPremult(const TPixel32 &bot, const TPixel32 &top)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return quickOverPixPremultT<tpixel32, uchar="">(bot, top);</tpixel32,>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI inline TPixel64 quickOverPix(const TPixel64 &bot, const TPixel64 &top)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return quickOverPixT<tpixel64, ushort="">(bot, top);</tpixel64,>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI inline TPixel32 quickOverPixDarkenBlended(const TPixel32 &bot, const TPixel32 &top)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return quickOverPixDarkenBlendedT<tpixel32, uchar="">(bot, top);</tpixel32,>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class class="" q="" t,=""></class>
Toshihiro Shimizu 890ddd
DVAPI inline void overPix(T &outPix, const T &bot, const T &top)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	UINT max = T::maxChannelValue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (top.m == max)
Toshihiro Shimizu 890ddd
		outPix = top;
Toshihiro Shimizu 890ddd
	else if (top.m == 0)
Toshihiro Shimizu 890ddd
		outPix = bot;
Toshihiro Shimizu 890ddd
	else {
Toshihiro Shimizu 890ddd
		TUINT32 r = top.r + bot.r * (max - top.m) / max;
Toshihiro Shimizu 890ddd
		TUINT32 g = top.g + bot.g * (max - top.m) / max;
Toshihiro Shimizu 890ddd
		TUINT32 b = top.b + bot.b * (max - top.m) / max;
Toshihiro Shimizu 890ddd
		outPix.r = (r < max) ? (Q)r : (Q)max,
Toshihiro Shimizu 890ddd
		outPix.g = (g < max) ? (Q)g : (Q)max,
Toshihiro Shimizu 890ddd
		outPix.b = (b < max) ? (Q)b : (Q)max,
Toshihiro Shimizu 890ddd
		outPix.m = (bot.m == max) ? max : max - (max - bot.m) * (max - top.m) / max;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI inline TPixel32 overPixOnWhite(const TPixel32 &top)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	UINT max = TPixel32::maxChannelValue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (top.m == max)
Toshihiro Shimizu 890ddd
		return top;
Toshihiro Shimizu 890ddd
	else if (top.m == 0)
Toshihiro Shimizu 890ddd
		return TPixel32::White;
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		return TPixel32(top.r + max - top.m,
Toshihiro Shimizu 890ddd
						top.g + max - top.m,
Toshihiro Shimizu 890ddd
						top.b + max - top.m,
Toshihiro Shimizu 890ddd
						max);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI inline TPixel32 overPixOnBlack(const TPixel32 &top)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	UINT max = TPixel32::maxChannelValue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (top.m == max)
Toshihiro Shimizu 890ddd
		return top;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (top.m == 0)
Toshihiro Shimizu 890ddd
		return TPixel32::Black;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return TPixel32(top.r, top.g, top.b, max);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*! this function combines two GR8 pixels returning the darker.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI inline TPixelGR8 over(const TPixelGR8 &bot, const TPixelGR8 &top)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return TPixelGR8(tmin(bot.value, top.value));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*! this function premultiply a not-premultiplied pixel.
Toshihiro Shimizu 890ddd
    \note 
Toshihiro Shimizu 890ddd
     Premultiplied alpha is a term used to describe a source color, 
Toshihiro Shimizu 890ddd
     the components of which have already been multiplied by an alpha value. 
Toshihiro Shimizu 890ddd
     Premultiplied alpha is just a different way of representing alphified pixels. 
Toshihiro Shimizu 890ddd
     If the separate alpha pixel is (r, g, b, a), then the premultiplied alpha pixel is 
Toshihiro Shimizu 890ddd
     (ar, ag, ab, a).
Toshihiro Shimizu 890ddd
     Premultiplying speeds up the rendering of the image by eliminating an extra 
Toshihiro Shimizu 890ddd
     multiplication operation per color component. 
Toshihiro Shimizu 890ddd
     For example, in an RGB color space, rendering the image with premultiplied alpha 
Toshihiro Shimizu 890ddd
     eliminates three multiplication operations (red times alpha, green times alpha, 
Toshihiro Shimizu 890ddd
     and blue times alpha) for each pixel in the image.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
     (Without premultiplication, the calculation to composite an image w/alpha into a comp is: 
Toshihiro Shimizu 890ddd
         dest = pix1 * alpha1 + (1 - alpha1) * pix2 * alpha2 
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
     If both images' alphas are premultiplied, this gets reduced to: 
Toshihiro Shimizu 890ddd
         dest = pix1 + (1 - alpha1) * pix2 
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI inline void premult(TPixel32 &pix)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	const int MAGICFAC = (257U * 256U + 1U);
Toshihiro Shimizu 890ddd
	UINT fac = MAGICFAC * pix.m;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	pix.r = (UINT)(pix.r * fac + (1U << 23)) >> 24;
Toshihiro Shimizu 890ddd
	pix.g = (UINT)(pix.g * fac + (1U << 23)) >> 24;
Toshihiro Shimizu 890ddd
	pix.b = (UINT)(pix.b * fac + (1U << 23)) >> 24;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI inline void premult(TPixel64 &pix)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	pix.r = pix.r * pix.m / 65535.0;
Toshihiro Shimizu 890ddd
	pix.g = pix.g * pix.m / 65535.0;
Toshihiro Shimizu 890ddd
	pix.b = pix.b * pix.m / 65535.0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI inline void depremult(TPixel32 &pix)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	float fac = 255.0f / pix.m;
Toshihiro Shimizu 890ddd
	pix.r = tmin(pix.r * fac, 255.0f);
Toshihiro Shimizu 890ddd
	pix.g = tmin(pix.g * fac, 255.0f);
Toshihiro Shimizu 890ddd
	pix.b = tmin(pix.b * fac, 255.0f);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI inline void depremult(TPixel64 &pix)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double fac = 65535.0 / pix.m;
Toshihiro Shimizu 890ddd
	pix.r = tmin(pix.r * fac, 65535.0);
Toshihiro Shimizu 890ddd
	pix.g = tmin(pix.g * fac, 65535.0);
Toshihiro Shimizu 890ddd
	pix.b = tmin(pix.b * fac, 65535.0);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename chan=""></typename>
Toshihiro Shimizu 890ddd
const double *premultiplyTable();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename chan=""></typename>
Toshihiro Shimizu 890ddd
const double *depremultiplyTable();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI inline TPixel32 premultiply(const TPixel32 &pix)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	const int MAGICFAC = (257U * 256U + 1U);
Toshihiro Shimizu 890ddd
	UINT fac = MAGICFAC * pix.m;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return TPixel32(
Toshihiro Shimizu 890ddd
		((UINT)(pix.r * fac + (1U << 23)) >> 24),
Toshihiro Shimizu 890ddd
		((UINT)(pix.g * fac + (1U << 23)) >> 24),
Toshihiro Shimizu 890ddd
		((UINT)(pix.b * fac + (1U << 23)) >> 24),
Toshihiro Shimizu 890ddd
		pix.m);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI inline TPixel64 premultiply(const TPixel64 &pix)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return TPixel64(
Toshihiro Shimizu 890ddd
		pix.r * pix.m / 65535.0,
Toshihiro Shimizu 890ddd
		pix.g * pix.m / 65535.0,
Toshihiro Shimizu 890ddd
		pix.b * pix.m / 65535.0,
Toshihiro Shimizu 890ddd
		pix.m);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI inline TPixel32 depremultiply(const TPixel32 &pix)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return TPixel32(
Toshihiro Shimizu 890ddd
		pix.r * 255.0 / pix.m,
Toshihiro Shimizu 890ddd
		pix.g * 255.0 / pix.m,
Toshihiro Shimizu 890ddd
		pix.b * 255.0 / pix.m,
Toshihiro Shimizu 890ddd
		pix.m);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI inline TPixel64 depremultiply(const TPixel64 &pix)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return TPixel64(
Toshihiro Shimizu 890ddd
		pix.r * 65535.0 / pix.m,
Toshihiro Shimizu 890ddd
		pix.g * 65535.0 / pix.m,
Toshihiro Shimizu 890ddd
		pix.b * 65535.0 / pix.m,
Toshihiro Shimizu 890ddd
		pix.m);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! onversion between RGB and HSV colorspace
Toshihiro Shimizu 890ddd
DVAPI void hsv2rgb(TPixel32 &dstRgb, int srcHsv[3], int maxHsv = 255);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  IN : h in [0..360], s and v in [0..1]
Toshihiro Shimizu 890ddd
  OUT: r,g,b in [0..1]
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
DVAPI void HSV2RGB(double hue, double sat, double value,
Toshihiro Shimizu 890ddd
				   double *red, double *green, double *blue);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI void rgb2hsv(int dstHsv[3], const TPixel32 &srcRgb, int maxHsv = 255);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI void RGB2HSV(double r, double g, double b,
Toshihiro Shimizu 890ddd
				   double *h, double *s, double *v);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  IN : h in [0..360], l and s in [0..1]
Toshihiro Shimizu 890ddd
  OUT: r,g,b in [0..1]
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI void HLS2RGB(double h, double l, double s,
Toshihiro Shimizu 890ddd
				   double *r, double *g, double *b);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  IN : r,g,b in [0..1]
Toshihiro Shimizu 890ddd
  OUT: h in [0..360], l and s in [0..1]
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI void rgb2hls(double r, double g, double b,
Toshihiro Shimizu 890ddd
				   double *h, double *l, double *s);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI TPixel32 toPixel32(const TPixel64 &);
Toshihiro Shimizu 890ddd
DVAPI TPixel32 toPixel32(const TPixelD &);
Toshihiro Shimizu 890ddd
DVAPI TPixel32 toPixel32(const TPixelGR8 &);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI TPixel64 toPixel64(const TPixel32 &);
Toshihiro Shimizu 890ddd
DVAPI TPixel64 toPixel64(const TPixelD &);
Toshihiro Shimizu 890ddd
DVAPI TPixel64 toPixel64(const TPixelGR8 &);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI TPixelD toPixelD(const TPixel32 &);
Toshihiro Shimizu 890ddd
DVAPI TPixelD toPixelD(const TPixel64 &);
Toshihiro Shimizu 890ddd
DVAPI TPixelD toPixelD(const TPixelGR8 &);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// nel caso in cui il tipo di destinazione sia il parametro di un template
Toshihiro Shimizu 890ddd
// es. template<pixel> ....</pixel>
Toshihiro Shimizu 890ddd
// si fa cosi':
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// PIXEL c = PixelConverter<pixel>::from(c1)</pixel>
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
class PixelConverter
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	inline static T from(const TPixel32 &pix);
Toshihiro Shimizu 890ddd
	inline static T from(const TPixel64 &pix);
Toshihiro Shimizu 890ddd
	inline static T from(const TPixelD &pix);
Toshihiro Shimizu 890ddd
	inline static T from(const TPixelGR8 &pix);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <>
Toshihiro Shimizu 890ddd
class PixelConverter<tpixel32></tpixel32>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	inline static TPixel32 from(const TPixel32 &pix) { return pix; }
Toshihiro Shimizu 890ddd
	inline static TPixel32 from(const TPixel64 &pix) { return toPixel32(pix); }
Toshihiro Shimizu 890ddd
	inline static TPixel32 from(const TPixelD &pix) { return toPixel32(pix); }
Toshihiro Shimizu 890ddd
	inline static TPixel32 from(const TPixelGR8 &pix) { return toPixel32(pix); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <>
Toshihiro Shimizu 890ddd
class PixelConverter<tpixel64></tpixel64>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	inline static TPixel64 from(const TPixel32 &pix) { return toPixel64(pix); }
Toshihiro Shimizu 890ddd
	inline static TPixel64 from(const TPixel64 &pix) { return pix; }
Toshihiro Shimizu 890ddd
	inline static TPixel64 from(const TPixelD &pix) { return toPixel64(pix); }
Toshihiro Shimizu 890ddd
	inline static TPixel64 from(const TPixelGR8 &pix) { return toPixel64(pix); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <>
Toshihiro Shimizu 890ddd
class PixelConverter<tpixeld></tpixeld>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	inline static TPixelD from(const TPixel32 &pix) { return toPixelD(pix); }
Toshihiro Shimizu 890ddd
	inline static TPixelD from(const TPixel64 &pix) { return toPixelD(pix); }
Toshihiro Shimizu 890ddd
	inline static TPixelD from(const TPixelD &pix) { return pix; }
Toshihiro Shimizu 890ddd
	inline static TPixelD from(const TPixelGR8 &pix) { return toPixelD(pix); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
void add(T &pixout, const T &pixin, double v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TINT32 r, g, b, m;
Toshihiro Shimizu 890ddd
	r = pixout.r + tround(pixin.r * v);
Toshihiro Shimizu 890ddd
	g = pixout.g + tround(pixin.g * v);
Toshihiro Shimizu 890ddd
	b = pixout.b + tround(pixin.b * v);
Toshihiro Shimizu 890ddd
	m = pixout.m + tround(pixin.m * v);
Toshihiro Shimizu 890ddd
	pixout.r = tcrop<tint32>(r, 0, T::maxChannelValue);</tint32>
Toshihiro Shimizu 890ddd
	pixout.g = tcrop<tint32>(g, 0, T::maxChannelValue);</tint32>
Toshihiro Shimizu 890ddd
	pixout.b = tcrop<tint32>(b, 0, T::maxChannelValue);</tint32>
Toshihiro Shimizu 890ddd
	pixout.m = tcrop<tint32>(m, 0, T::maxChannelValue);</tint32>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
void sub(T &pixout, const T &pixin, double v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TINT32 r, g, b, m;
Toshihiro Shimizu 890ddd
	r = pixout.r - (pixin.r * v);
Toshihiro Shimizu 890ddd
	g = pixout.g - (pixin.g * v);
Toshihiro Shimizu 890ddd
	b = pixout.b - (pixin.b * v);
Toshihiro Shimizu 890ddd
	m = pixout.m - (pixin.m * v);
Toshihiro Shimizu 890ddd
	pixout.r = tcrop<tint32>(r, 0, T::maxChannelValue);</tint32>
Toshihiro Shimizu 890ddd
	pixout.g = tcrop<tint32>(g, 0, T::maxChannelValue);</tint32>
Toshihiro Shimizu 890ddd
	pixout.b = tcrop<tint32>(b, 0, T::maxChannelValue);</tint32>
Toshihiro Shimizu 890ddd
	pixout.m = tcrop<tint32>(m, 0, T::maxChannelValue);</tint32>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//!Multiplies \b pixout by \b pixin. Passed parameter \b v stands for a further additive
Toshihiro Shimizu 890ddd
//!component on pixin.
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
void mult(T &pixout, const T &pixin, double v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double r, g, b, m;
Toshihiro Shimizu 890ddd
	r = pixin.r + v;
Toshihiro Shimizu 890ddd
	g = pixin.g + v;
Toshihiro Shimizu 890ddd
	b = pixin.b + v;
Toshihiro Shimizu 890ddd
	m = pixin.m + v;
Toshihiro Shimizu 890ddd
	pixout.r = (r < 0) ? 0 : ((r < T::maxChannelValue) ? troundp(r * (pixout.r / (double)T::maxChannelValue)) : pixout.r);
Toshihiro Shimizu 890ddd
	pixout.g = (g < 0) ? 0 : ((g < T::maxChannelValue) ? troundp(g * (pixout.g / (double)T::maxChannelValue)) : pixout.g);
Toshihiro Shimizu 890ddd
	pixout.b = (b < 0) ? 0 : ((b < T::maxChannelValue) ? troundp(b * (pixout.b / (double)T::maxChannelValue)) : pixout.b);
Toshihiro Shimizu 890ddd
	pixout.m = (m < 0) ? 0 : ((m < T::maxChannelValue) ? troundp(m * (pixout.m / (double)T::maxChannelValue)) : pixout.m);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//!Substitutes \b pixout components with those of \b pixin, when the latters are greater.
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
void lighten(T &pixout, const T &pixin, double v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	pixout.r = pixin.r > pixout.r ? pixin.r : pixout.r;
Toshihiro Shimizu 890ddd
	pixout.g = pixin.g > pixout.g ? pixin.g : pixout.g;
Toshihiro Shimizu 890ddd
	pixout.b = pixin.b > pixout.b ? pixin.b : pixout.b;
Toshihiro Shimizu 890ddd
	pixout.m = pixin.m > pixout.m ? pixin.m : pixout.m;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//!Substitutes \b pixout components with those of \b pixin, when the latters are smaller.
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
void darken(T &pixout, const T &pixin, double v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	pixout.r = pixin.r < pixout.r ? pixin.r : pixout.r;
Toshihiro Shimizu 890ddd
	pixout.g = pixin.g < pixout.g ? pixin.g : pixout.g;
Toshihiro Shimizu 890ddd
	pixout.b = pixin.b < pixout.b ? pixin.b : pixout.b;
Toshihiro Shimizu 890ddd
	pixout.m = pixin.m < pixout.m ? pixin.m : pixout.m;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif