|
Shinya Kitaoka |
810553 |
#pragma once
|
|
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 |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
/*! 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>
|
|
Shinya Kitaoka |
120a6e |
inline T blend(const T &a, const T &b, double t) {
|
|
Shinya Kitaoka |
120a6e |
return T(troundp((1 - t) * a.r + t * b.r), troundp((1 - t) * a.g + t * b.g),
|
|
Shinya Kitaoka |
120a6e |
troundp((1 - t) * a.b + t * b.b), troundp((1 - t) * a.m + t * b.m));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
/*! 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;
|
|
Shinya Kitaoka |
120a6e |
No check is performed.
|
|
Toshihiro Shimizu |
890ddd |
\warning \b b MUST be not zero.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Shinya Kitaoka |
120a6e |
inline T blend(const T &a, const T &b, int num, int den) {
|
|
Shinya Kitaoka |
120a6e |
return T((int)(((den - num) * a.r + num * b.r) / den),
|
|
Shinya Kitaoka |
120a6e |
(int)(((den - num) * a.g + num * b.g) / den),
|
|
Shinya Kitaoka |
120a6e |
(int)(((den - num) * a.b + num * b.b) / den),
|
|
Shinya Kitaoka |
120a6e |
(int)(((den - num) * a.m + num * b.m) / den));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Shinya Kitaoka |
120a6e |
inline T antialias(const T &a, int num) {
|
|
Shinya Kitaoka |
120a6e |
return T((int)((num * a.r) / 255), (int)((num * a.g) / 255),
|
|
Shinya Kitaoka |
120a6e |
(int)((num * a.b) / 255), (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>
|
|
|
2fc36c |
inline T overPixT(const T &bot, const T &top) {
|
|
Shinya Kitaoka |
120a6e |
UINT max = T::maxChannelValue;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (top.m == max) return top;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (top.m == 0) return bot;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TUINT32 r = top.r + bot.r * (max - top.m) / max;
|
|
Shinya Kitaoka |
120a6e |
TUINT32 g = top.g + bot.g * (max - top.m) / max;
|
|
Shinya Kitaoka |
120a6e |
TUINT32 b = top.b + bot.b * (max - top.m) / max;
|
|
Shinya Kitaoka |
120a6e |
return T((r < max) ? (Q)r : (Q)max, (g < max) ? (Q)g : (Q)max,
|
|
Shinya Kitaoka |
120a6e |
(b < max) ? (Q)b : (Q)max,
|
|
Shinya Kitaoka |
120a6e |
(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>
|
|
|
2fc36c |
inline T overPixGRT(const T &bot, const S &top) {
|
|
Shinya Kitaoka |
120a6e |
UINT max = T::maxChannelValue;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (top.value == max) return T(top.value, top.value, top.value, top.value);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (top.value == 0) return bot;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double aux = (max - top.value) / max;
|
|
Shinya Kitaoka |
120a6e |
TUINT32 r = (TUINT32)(top.value + bot.r * aux);
|
|
Shinya Kitaoka |
120a6e |
TUINT32 g = (TUINT32)(top.value + bot.g * aux);
|
|
Shinya Kitaoka |
120a6e |
TUINT32 b = (TUINT32)(top.value + bot.b * aux);
|
|
Shinya Kitaoka |
120a6e |
return T((r < max) ? (Q)r : (Q)max, (g < max) ? (Q)g : (Q)max,
|
|
Shinya Kitaoka |
120a6e |
(b < max) ? (Q)b : (Q)max,
|
|
Shinya Kitaoka |
120a6e |
(bot.m == max) ? max : (TUINT32)(max - (max - bot.m) * aux));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
// as the other, but without if's. it's quicker if you know for sure that top.m
|
|
Shinya Kitaoka |
120a6e |
// is not 0 or 255.
|
|
Toshihiro Shimizu |
890ddd |
template <class class="" q="" t,=""></class>
|
|
|
2fc36c |
inline T quickOverPixT(const T &bot, const T &top) {
|
|
Shinya Kitaoka |
120a6e |
UINT max = T::maxChannelValue;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TUINT32 r = top.r + bot.r * (max - top.m) / max;
|
|
Shinya Kitaoka |
120a6e |
TUINT32 g = top.g + bot.g * (max - top.m) / max;
|
|
Shinya Kitaoka |
120a6e |
TUINT32 b = top.b + bot.b * (max - top.m) / max;
|
|
Shinya Kitaoka |
120a6e |
return T((r < max) ? (Q)r : (Q)max, (g < max) ? (Q)g : (Q)max,
|
|
Shinya Kitaoka |
120a6e |
(b < max) ? (Q)b : (Q)max,
|
|
Shinya Kitaoka |
120a6e |
(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>
|
|
|
2fc36c |
inline T quickOverPixPremultT(const T &bot, const T &top) {
|
|
Shinya Kitaoka |
120a6e |
UINT max = T::maxChannelValue;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TUINT32 r = (top.r * top.m + bot.r * (max - top.m)) / max;
|
|
Shinya Kitaoka |
120a6e |
TUINT32 g = (top.g * top.m + bot.g * (max - top.m)) / max;
|
|
Shinya Kitaoka |
120a6e |
TUINT32 b = (top.b * top.m + bot.b * (max - top.m)) / max;
|
|
Shinya Kitaoka |
120a6e |
return T((r < max) ? (Q)r : (Q)max, (g < max) ? (Q)g : (Q)max,
|
|
Shinya Kitaoka |
120a6e |
(b < max) ? (Q)b : (Q)max,
|
|
Shinya Kitaoka |
120a6e |
(bot.m == max) ? max : max - (max - bot.m) * (max - top.m) / max);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------------
|
|
shun_iwasawa |
21a6b6 |
/*-- Show raster images darken-blended on the viewer --*/
|
|
shun_iwasawa |
a3cdd8 |
/* references from ino_blend_darken.cpp */
|
|
Toshihiro Shimizu |
890ddd |
template <class class="" q="" t,=""></class>
|
|
|
2fc36c |
inline T quickOverPixDarkenBlendedT(const T &bot, const T &top) {
|
|
shun_iwasawa |
a3cdd8 |
struct locals {
|
|
shun_iwasawa |
a3cdd8 |
static inline double comp(const double ch_a, const double ch_b,
|
|
shun_iwasawa |
a3cdd8 |
const double alpha) {
|
|
shun_iwasawa |
a3cdd8 |
return clamp(ch_b + ch_a * (1.0 - alpha));
|
|
shun_iwasawa |
a3cdd8 |
}
|
|
shun_iwasawa |
a3cdd8 |
static inline double darken_ch(const double dn, const double dn_a,
|
|
shun_iwasawa |
a3cdd8 |
const double up, const double up_a) {
|
|
shun_iwasawa |
a3cdd8 |
return (up / up_a < dn / dn_a) ? comp(dn, up, up_a) : comp(up, dn, dn_a);
|
|
shun_iwasawa |
a3cdd8 |
}
|
|
shun_iwasawa |
a3cdd8 |
static inline double clamp(double val) {
|
|
shun_iwasawa |
a3cdd8 |
return (val < 0.0) ? 0.0 : (val > 1.0) ? 1.0 : val;
|
|
shun_iwasawa |
a3cdd8 |
}
|
|
shun_iwasawa |
a3cdd8 |
}; // locals
|
|
shun_iwasawa |
a3cdd8 |
|
|
shun_iwasawa |
21a6b6 |
if (bot.m == 0) return top;
|
|
shun_iwasawa |
a3cdd8 |
|
|
shun_iwasawa |
a3cdd8 |
if (top.m == T::maxChannelValue && bot.m == T::maxChannelValue) {
|
|
shun_iwasawa |
a3cdd8 |
TUINT32 r = (top.r < bot.r) ? top.r : bot.r;
|
|
shun_iwasawa |
a3cdd8 |
TUINT32 g = (top.g < bot.g) ? top.g : bot.g;
|
|
shun_iwasawa |
a3cdd8 |
TUINT32 b = (top.b < bot.b) ? top.b : bot.b;
|
|
shun_iwasawa |
a3cdd8 |
return T((Q)r, (Q)g, (Q)b, T::maxChannelValue);
|
|
shun_iwasawa |
a3cdd8 |
}
|
|
shun_iwasawa |
a3cdd8 |
|
|
shun_iwasawa |
a3cdd8 |
double maxi = static_cast<double>(T::maxChannelValue); // 255or65535</double>
|
|
shun_iwasawa |
a3cdd8 |
|
|
shun_iwasawa |
a3cdd8 |
double upr = static_cast<double>(top.r) / maxi;</double>
|
|
shun_iwasawa |
a3cdd8 |
double upg = static_cast<double>(top.g) / maxi;</double>
|
|
shun_iwasawa |
a3cdd8 |
double upb = static_cast<double>(top.b) / maxi;</double>
|
|
shun_iwasawa |
a3cdd8 |
double upa = static_cast<double>(top.m) / maxi;</double>
|
|
shun_iwasawa |
a3cdd8 |
double dnr = static_cast<double>(bot.r) / maxi;</double>
|
|
shun_iwasawa |
a3cdd8 |
double dng = static_cast<double>(bot.g) / maxi;</double>
|
|
shun_iwasawa |
a3cdd8 |
double dnb = static_cast<double>(bot.b) / maxi;</double>
|
|
shun_iwasawa |
a3cdd8 |
double dna = static_cast<double>(bot.m) / maxi;</double>
|
|
shun_iwasawa |
a3cdd8 |
dnr = locals::darken_ch(dnr, dna, upr, upa);
|
|
shun_iwasawa |
a3cdd8 |
dng = locals::darken_ch(dng, dna, upg, upa);
|
|
shun_iwasawa |
a3cdd8 |
dnb = locals::darken_ch(dnb, dna, upb, upa);
|
|
shun_iwasawa |
a3cdd8 |
dna = locals::comp(dna, upa, upa);
|
|
shun_iwasawa |
a3cdd8 |
T out;
|
|
shun_iwasawa |
a3cdd8 |
out.r = static_cast<q>(dnr * (maxi + 0.999999));</q>
|
|
shun_iwasawa |
a3cdd8 |
out.g = static_cast<q>(dng * (maxi + 0.999999));</q>
|
|
shun_iwasawa |
a3cdd8 |
out.b = static_cast<q>(dnb * (maxi + 0.999999));</q>
|
|
shun_iwasawa |
a3cdd8 |
out.m = static_cast<q>(dna * (maxi + 0.999999));</q>
|
|
shun_iwasawa |
a3cdd8 |
return out;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
template <class class="" q="" s,="" t,=""></class>
|
|
|
2fc36c |
inline T quickOverPixGRT(const T &bot, const S &top) {
|
|
Shinya Kitaoka |
120a6e |
UINT max = T::maxChannelValue;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double aux = (max - top.value) / max;
|
|
Shinya Kitaoka |
120a6e |
TUINT32 r = (TUINT32)(top.value + bot.r * aux);
|
|
Shinya Kitaoka |
120a6e |
TUINT32 g = (TUINT32)(top.value + bot.g * aux);
|
|
Shinya Kitaoka |
120a6e |
TUINT32 b = (TUINT32)(top.value + bot.b * aux);
|
|
Shinya Kitaoka |
120a6e |
return T((r < max) ? (Q)r : (Q)max, (g < max) ? (Q)g : (Q)max,
|
|
Shinya Kitaoka |
120a6e |
(b < max) ? (Q)b : (Q)max,
|
|
Shinya Kitaoka |
120a6e |
(bot.m == max) ? max : (TUINT32)(max - (max - bot.m) * aux));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
2fc36c |
inline TPixel32 overPix(const TPixel32 &bot, const TPixelGR8 &top) {
|
|
Shinya Kitaoka |
120a6e |
return overPixGRT<tpixel32, tpixelgr8,="" uchar="">(bot, top);</tpixel32,>
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
2fc36c |
inline TPixel64 overPix(const TPixel64 &bot, const TPixelGR16 &top) {
|
|
Shinya Kitaoka |
120a6e |
return overPixGRT<tpixel64, tpixelgr16,="" ushort="">(bot, top);</tpixel64,>
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
2fc36c |
inline TPixel32 overPix(const TPixel32 &bot, const TPixel32 &top) {
|
|
Shinya Kitaoka |
120a6e |
return overPixT<tpixel32, uchar="">(bot, top);</tpixel32,>
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
2fc36c |
inline TPixel64 overPix(const TPixel64 &bot, const TPixel64 &top) {
|
|
Shinya Kitaoka |
120a6e |
return overPixT<tpixel64, ushort="">(bot, top);</tpixel64,>
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
2fc36c |
inline TPixel32 quickOverPix(const TPixel32 &bot, const TPixelGR8 &top) {
|
|
Shinya Kitaoka |
120a6e |
return quickOverPixGRT<tpixel32, tpixelgr8,="" uchar="">(bot, top);</tpixel32,>
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
2fc36c |
inline TPixel64 quickOverPix(const TPixel64 &bot, const TPixelGR16 &top) {
|
|
Shinya Kitaoka |
120a6e |
return quickOverPixGRT<tpixel64, tpixelgr16,="" ushort="">(bot, top);</tpixel64,>
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
2fc36c |
inline TPixel32 quickOverPix(const TPixel32 &bot, const TPixel32 &top) {
|
|
Shinya Kitaoka |
120a6e |
return quickOverPixT<tpixel32, uchar="">(bot, top);</tpixel32,>
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
5b7b9f |
inline TPixel32 quickOverPixPremult(const TPixel32 &bot, const TPixel32 &top) {
|
|
Shinya Kitaoka |
120a6e |
return quickOverPixPremultT<tpixel32, uchar="">(bot, top);</tpixel32,>
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
2fc36c |
inline TPixel64 quickOverPix(const TPixel64 &bot, const TPixel64 &top) {
|
|
Shinya Kitaoka |
120a6e |
return quickOverPixT<tpixel64, ushort="">(bot, top);</tpixel64,>
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
2fc36c |
inline TPixel32 quickOverPixDarkenBlended(const TPixel32 &bot,
|
|
|
2fc36c |
const TPixel32 &top) {
|
|
Shinya Kitaoka |
120a6e |
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>
|
|
|
2fc36c |
inline void overPix(T &outPix, const T &bot, const T &top) {
|
|
Shinya Kitaoka |
120a6e |
UINT max = T::maxChannelValue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (top.m == max)
|
|
Shinya Kitaoka |
120a6e |
outPix = top;
|
|
Shinya Kitaoka |
120a6e |
else if (top.m == 0)
|
|
Shinya Kitaoka |
120a6e |
outPix = bot;
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
TUINT32 r = top.r + bot.r * (max - top.m) / max;
|
|
Shinya Kitaoka |
120a6e |
TUINT32 g = top.g + bot.g * (max - top.m) / max;
|
|
Shinya Kitaoka |
120a6e |
TUINT32 b = top.b + bot.b * (max - top.m) / max;
|
|
Shinya Kitaoka |
120a6e |
outPix.r = (r < max) ? (Q)r : (Q)max, outPix.g = (g < max) ? (Q)g : (Q)max,
|
|
Shinya Kitaoka |
120a6e |
outPix.b = (b < max) ? (Q)b : (Q)max,
|
|
Shinya Kitaoka |
120a6e |
outPix.m = (bot.m == max) ? max : max - (max - bot.m) * (max - top.m) / max;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
2fc36c |
inline TPixel32 overPixOnWhite(const TPixel32 &top) {
|
|
Shinya Kitaoka |
120a6e |
UINT max = TPixel32::maxChannelValue;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (top.m == max)
|
|
Shinya Kitaoka |
120a6e |
return top;
|
|
Shinya Kitaoka |
120a6e |
else if (top.m == 0)
|
|
Shinya Kitaoka |
120a6e |
return TPixel32::White;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
return TPixel32(top.r + max - top.m, top.g + max - top.m,
|
|
Shinya Kitaoka |
120a6e |
top.b + max - top.m, max);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
2fc36c |
inline TPixel32 overPixOnBlack(const TPixel32 &top) {
|
|
Shinya Kitaoka |
120a6e |
UINT max = TPixel32::maxChannelValue;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (top.m == max) return top;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (top.m == 0) return TPixel32::Black;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
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 |
|
|
|
2fc36c |
inline TPixelGR8 over(const TPixelGR8 &bot, const TPixelGR8 &top) {
|
|
Shinya Kitaoka |
120a6e |
return TPixelGR8(std::min(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.
|
|
Shinya Kitaoka |
120a6e |
\note
|
|
Shinya Kitaoka |
120a6e |
Premultiplied alpha is a term used to describe a source color,
|
|
Shinya Kitaoka |
120a6e |
the components of which have already been multiplied by an alpha value.
|
|
Shinya Kitaoka |
120a6e |
Premultiplied alpha is just a different way of representing alphified
|
|
Shinya Kitaoka |
120a6e |
pixels.
|
|
Shinya Kitaoka |
120a6e |
If the separate alpha pixel is (r, g, b, a), then the premultiplied alpha
|
|
Shinya Kitaoka |
120a6e |
pixel is
|
|
Toshihiro Shimizu |
890ddd |
(ar, ag, ab, a).
|
|
Shinya Kitaoka |
120a6e |
Premultiplying speeds up the rendering of the image by eliminating an extra
|
|
Shinya Kitaoka |
120a6e |
multiplication operation per color component.
|
|
Shinya Kitaoka |
120a6e |
For example, in an RGB color space, rendering the image with premultiplied
|
|
Shinya Kitaoka |
120a6e |
alpha
|
|
Shinya Kitaoka |
120a6e |
eliminates three multiplication operations (red times alpha, green times
|
|
Shinya Kitaoka |
120a6e |
alpha,
|
|
Toshihiro Shimizu |
890ddd |
and blue times alpha) for each pixel in the image.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
(Without premultiplication, the calculation to composite an image w/alpha
|
|
Shinya Kitaoka |
120a6e |
into a comp is:
|
|
Shinya Kitaoka |
120a6e |
dest = pix1 * alpha1 + (1 - alpha1) * pix2 * alpha2
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
If both images' alphas are premultiplied, this gets reduced to:
|
|
Shinya Kitaoka |
120a6e |
dest = pix1 + (1 - alpha1) * pix2
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
2fc36c |
inline void premult(TPixel32 &pix) {
|
|
Shinya Kitaoka |
120a6e |
const int MAGICFAC = (257U * 256U + 1U);
|
|
Shinya Kitaoka |
120a6e |
UINT fac = MAGICFAC * pix.m;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
pix.r = (UINT)(pix.r * fac + (1U << 23)) >> 24;
|
|
Shinya Kitaoka |
120a6e |
pix.g = (UINT)(pix.g * fac + (1U << 23)) >> 24;
|
|
Shinya Kitaoka |
120a6e |
pix.b = (UINT)(pix.b * fac + (1U << 23)) >> 24;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
2fc36c |
inline void premult(TPixel64 &pix) {
|
|
Shinya Kitaoka |
120a6e |
pix.r = pix.r * pix.m / 65535.0;
|
|
Shinya Kitaoka |
120a6e |
pix.g = pix.g * pix.m / 65535.0;
|
|
Shinya Kitaoka |
120a6e |
pix.b = pix.b * pix.m / 65535.0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
2fc36c |
inline void depremult(TPixel32 &pix) {
|
|
Shinya Kitaoka |
120a6e |
float fac = 255.0f / pix.m;
|
|
Shinya Kitaoka |
120a6e |
pix.r = std::min(pix.r * fac, 255.0f);
|
|
Shinya Kitaoka |
120a6e |
pix.g = std::min(pix.g * fac, 255.0f);
|
|
Shinya Kitaoka |
120a6e |
pix.b = std::min(pix.b * fac, 255.0f);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
2fc36c |
inline void depremult(TPixel64 &pix) {
|
|
Shinya Kitaoka |
120a6e |
double fac = 65535.0 / pix.m;
|
|
Shinya Kitaoka |
120a6e |
pix.r = std::min(pix.r * fac, 65535.0);
|
|
Shinya Kitaoka |
120a6e |
pix.g = std::min(pix.g * fac, 65535.0);
|
|
Shinya Kitaoka |
120a6e |
pix.b = std::min(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 |
|
|
|
2fc36c |
inline TPixel32 premultiply(const TPixel32 &pix) {
|
|
Shinya Kitaoka |
120a6e |
const int MAGICFAC = (257U * 256U + 1U);
|
|
Shinya Kitaoka |
120a6e |
UINT fac = MAGICFAC * pix.m;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return TPixel32(((UINT)(pix.r * fac + (1U << 23)) >> 24),
|
|
Shinya Kitaoka |
120a6e |
((UINT)(pix.g * fac + (1U << 23)) >> 24),
|
|
Shinya Kitaoka |
120a6e |
((UINT)(pix.b * fac + (1U << 23)) >> 24), pix.m);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
2fc36c |
inline TPixel64 premultiply(const TPixel64 &pix) {
|
|
Shinya Kitaoka |
120a6e |
return TPixel64(pix.r * pix.m / 65535.0, pix.g * pix.m / 65535.0,
|
|
Shinya Kitaoka |
120a6e |
pix.b * pix.m / 65535.0, pix.m);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
2fc36c |
inline TPixel32 depremultiply(const TPixel32 &pix) {
|
|
Shinya Kitaoka |
120a6e |
return TPixel32(pix.r * 255.0 / pix.m, pix.g * 255.0 / pix.m,
|
|
Shinya Kitaoka |
120a6e |
pix.b * 255.0 / pix.m, pix.m);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
2fc36c |
inline TPixel64 depremultiply(const TPixel64 &pix) {
|
|
Shinya Kitaoka |
120a6e |
return TPixel64(pix.r * 65535.0 / pix.m, pix.g * 65535.0 / pix.m,
|
|
Shinya Kitaoka |
120a6e |
pix.b * 65535.0 / pix.m, 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 |
*/
|
|
Shinya Kitaoka |
120a6e |
DVAPI void HSV2RGB(double hue, double sat, double value, double *red,
|
|
Shinya Kitaoka |
120a6e |
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 |
|
|
Shinya Kitaoka |
120a6e |
DVAPI void RGB2HSV(double r, double g, double b, double *h, double *s,
|
|
Shinya Kitaoka |
120a6e |
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 |
|
|
Shinya Kitaoka |
120a6e |
DVAPI void HLS2RGB(double h, double l, double s, double *r, double *g,
|
|
Shinya Kitaoka |
120a6e |
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 |
|
|
Shinya Kitaoka |
120a6e |
DVAPI void rgb2hls(double r, double g, double b, double *h, double *l,
|
|
Shinya Kitaoka |
120a6e |
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>
|
|
Shinya Kitaoka |
120a6e |
class PixelConverter {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
inline static T from(const TPixel32 &pix);
|
|
Shinya Kitaoka |
120a6e |
inline static T from(const TPixel64 &pix);
|
|
Shinya Kitaoka |
120a6e |
inline static T from(const TPixelD &pix);
|
|
Shinya Kitaoka |
120a6e |
inline static T from(const TPixelGR8 &pix);
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <>
|
|
Shinya Kitaoka |
120a6e |
class PixelConverter<tpixel32> {</tpixel32>
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
inline static TPixel32 from(const TPixel32 &pix) { return pix; }
|
|
Shinya Kitaoka |
120a6e |
inline static TPixel32 from(const TPixel64 &pix) { return toPixel32(pix); }
|
|
Shinya Kitaoka |
120a6e |
inline static TPixel32 from(const TPixelD &pix) { return toPixel32(pix); }
|
|
Shinya Kitaoka |
120a6e |
inline static TPixel32 from(const TPixelGR8 &pix) { return toPixel32(pix); }
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <>
|
|
Shinya Kitaoka |
120a6e |
class PixelConverter<tpixel64> {</tpixel64>
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
inline static TPixel64 from(const TPixel32 &pix) { return toPixel64(pix); }
|
|
Shinya Kitaoka |
120a6e |
inline static TPixel64 from(const TPixel64 &pix) { return pix; }
|
|
Shinya Kitaoka |
120a6e |
inline static TPixel64 from(const TPixelD &pix) { return toPixel64(pix); }
|
|
Shinya Kitaoka |
120a6e |
inline static TPixel64 from(const TPixelGR8 &pix) { return toPixel64(pix); }
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <>
|
|
Shinya Kitaoka |
120a6e |
class PixelConverter<tpixeld> {</tpixeld>
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
inline static TPixelD from(const TPixel32 &pix) { return toPixelD(pix); }
|
|
Shinya Kitaoka |
120a6e |
inline static TPixelD from(const TPixel64 &pix) { return toPixelD(pix); }
|
|
Shinya Kitaoka |
120a6e |
inline static TPixelD from(const TPixelD &pix) { return pix; }
|
|
Shinya Kitaoka |
120a6e |
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>
|
|
Shinya Kitaoka |
120a6e |
void add(T &pixout, const T &pixin, double v) {
|
|
Shinya Kitaoka |
120a6e |
TINT32 r, g, b, m;
|
|
Shinya Kitaoka |
120a6e |
r = pixout.r + tround(pixin.r * v);
|
|
Shinya Kitaoka |
120a6e |
g = pixout.g + tround(pixin.g * v);
|
|
Shinya Kitaoka |
120a6e |
b = pixout.b + tround(pixin.b * v);
|
|
Shinya Kitaoka |
120a6e |
m = pixout.m + tround(pixin.m * v);
|
|
Shinya Kitaoka |
120a6e |
pixout.r = tcrop<tint32>(r, 0, T::maxChannelValue);</tint32>
|
|
Shinya Kitaoka |
120a6e |
pixout.g = tcrop<tint32>(g, 0, T::maxChannelValue);</tint32>
|
|
Shinya Kitaoka |
120a6e |
pixout.b = tcrop<tint32>(b, 0, T::maxChannelValue);</tint32>
|
|
Shinya Kitaoka |
120a6e |
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>
|
|
Shinya Kitaoka |
120a6e |
void sub(T &pixout, const T &pixin, double v) {
|
|
Shinya Kitaoka |
120a6e |
TINT32 r, g, b, m;
|
|
Shinya Kitaoka |
120a6e |
r = pixout.r - (pixin.r * v);
|
|
Shinya Kitaoka |
120a6e |
g = pixout.g - (pixin.g * v);
|
|
Shinya Kitaoka |
120a6e |
b = pixout.b - (pixin.b * v);
|
|
Shinya Kitaoka |
120a6e |
m = pixout.m - (pixin.m * v);
|
|
Shinya Kitaoka |
120a6e |
pixout.r = tcrop<tint32>(r, 0, T::maxChannelValue);</tint32>
|
|
Shinya Kitaoka |
120a6e |
pixout.g = tcrop<tint32>(g, 0, T::maxChannelValue);</tint32>
|
|
Shinya Kitaoka |
120a6e |
pixout.b = tcrop<tint32>(b, 0, T::maxChannelValue);</tint32>
|
|
Shinya Kitaoka |
120a6e |
pixout.m = tcrop<tint32>(m, 0, T::maxChannelValue);</tint32>
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Multiplies \b pixout by \b pixin. Passed parameter \b v stands for a further
|
|
Shinya Kitaoka |
120a6e |
//! additive
|
|
Shinya Kitaoka |
120a6e |
//! component on pixin.
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Shinya Kitaoka |
120a6e |
void mult(T &pixout, const T &pixin, double v) {
|
|
Shinya Kitaoka |
120a6e |
double r, g, b, m;
|
|
Shinya Kitaoka |
120a6e |
r = pixin.r + v;
|
|
Shinya Kitaoka |
120a6e |
g = pixin.g + v;
|
|
Shinya Kitaoka |
120a6e |
b = pixin.b + v;
|
|
Shinya Kitaoka |
120a6e |
m = pixin.m + v;
|
|
Shinya Kitaoka |
120a6e |
pixout.r =
|
|
Shinya Kitaoka |
120a6e |
(r < 0) ? 0 : ((r < T::maxChannelValue)
|
|
Shinya Kitaoka |
120a6e |
? troundp(r * (pixout.r / (double)T::maxChannelValue))
|
|
Shinya Kitaoka |
120a6e |
: pixout.r);
|
|
Shinya Kitaoka |
120a6e |
pixout.g =
|
|
Shinya Kitaoka |
120a6e |
(g < 0) ? 0 : ((g < T::maxChannelValue)
|
|
Shinya Kitaoka |
120a6e |
? troundp(g * (pixout.g / (double)T::maxChannelValue))
|
|
Shinya Kitaoka |
120a6e |
: pixout.g);
|
|
Shinya Kitaoka |
120a6e |
pixout.b =
|
|
Shinya Kitaoka |
120a6e |
(b < 0) ? 0 : ((b < T::maxChannelValue)
|
|
Shinya Kitaoka |
120a6e |
? troundp(b * (pixout.b / (double)T::maxChannelValue))
|
|
Shinya Kitaoka |
120a6e |
: pixout.b);
|
|
Shinya Kitaoka |
120a6e |
pixout.m =
|
|
Shinya Kitaoka |
120a6e |
(m < 0) ? 0 : ((m < T::maxChannelValue)
|
|
Shinya Kitaoka |
120a6e |
? troundp(m * (pixout.m / (double)T::maxChannelValue))
|
|
Shinya Kitaoka |
120a6e |
: pixout.m);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Substitutes \b pixout components with those of \b pixin, when the latters
|
|
Shinya Kitaoka |
120a6e |
//! are greater.
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Shinya Kitaoka |
120a6e |
void lighten(T &pixout, const T &pixin, double v) {
|
|
Shinya Kitaoka |
120a6e |
pixout.r = pixin.r > pixout.r ? pixin.r : pixout.r;
|
|
Shinya Kitaoka |
120a6e |
pixout.g = pixin.g > pixout.g ? pixin.g : pixout.g;
|
|
Shinya Kitaoka |
120a6e |
pixout.b = pixin.b > pixout.b ? pixin.b : pixout.b;
|
|
Shinya Kitaoka |
120a6e |
pixout.m = pixin.m > pixout.m ? pixin.m : pixout.m;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Substitutes \b pixout components with those of \b pixin, when the latters
|
|
Shinya Kitaoka |
120a6e |
//! are smaller.
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Shinya Kitaoka |
120a6e |
void darken(T &pixout, const T &pixin, double v) {
|
|
Shinya Kitaoka |
120a6e |
pixout.r = pixin.r < pixout.r ? pixin.r : pixout.r;
|
|
Shinya Kitaoka |
120a6e |
pixout.g = pixin.g < pixout.g ? pixin.g : pixout.g;
|
|
Shinya Kitaoka |
120a6e |
pixout.b = pixin.b < pixout.b ? pixin.b : pixout.b;
|
|
Shinya Kitaoka |
120a6e |
pixout.m = pixin.m < pixout.m ? pixin.m : pixout.m;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#endif
|