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