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
}