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
shun-iwasawa 481b59
template <>
shun-iwasawa 481b59
inline TPixelF blend(const TPixelF &a, const TPixelF &b, double t) {
shun-iwasawa 443318
  return TPixelF((float)(1. - t) * a.r + (float)t * b.r,
shun-iwasawa 443318
                 (float)(1. - t) * a.g + (float)t * b.g,
shun-iwasawa 443318
                 (float)(1. - t) * a.b + (float)t * b.b,
shun-iwasawa 443318
                 (float)(1. - t) * a.m + (float)t * b.m);
shun-iwasawa 481b59
}
shun-iwasawa 481b59
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
shun-iwasawa 481b59
template <>
shun-iwasawa 481b59
inline TPixelF overPixT<tpixelf, float="">(const TPixelF &bot,</tpixelf,>
shun-iwasawa 481b59
                                        const TPixelF &top) {
shun-iwasawa 481b59
  if (top.m >= 1.f) return top;
shun-iwasawa 481b59
shun-iwasawa 481b59
  if (top.m <= 0.f) return bot;
shun-iwasawa 481b59
shun-iwasawa 481b59
  float r = top.r + bot.r * (1.f - top.m);
shun-iwasawa 481b59
  float g = top.g + bot.g * (1.f - top.m);
shun-iwasawa 481b59
  float b = top.b + bot.b * (1.f - top.m);
shun-iwasawa 481b59
  return TPixelF(r, g, b,
shun-iwasawa 481b59
                 (bot.m >= 1.f) ? bot.m : 1.f - (1.f - bot.m) * (1.f - top.m));
shun-iwasawa 481b59
}
shun-iwasawa 481b59
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
shun-iwasawa 481b59
template <>
shun-iwasawa 481b59
inline TPixelF quickOverPixT<tpixelf, float="">(const TPixelF &bot,</tpixelf,>
shun-iwasawa 481b59
                                             const TPixelF &top) {
shun-iwasawa 481b59
  float r = top.r + bot.r * (1.f - top.m);
shun-iwasawa 481b59
  float g = top.g + bot.g * (1.f - top.m);
shun-iwasawa 481b59
  float b = top.b + bot.b * (1.f - top.m);
shun-iwasawa 481b59
  return TPixelF(r, g, b,
shun-iwasawa 481b59
                 (bot.m == 1.f) ? 1.f : 1.f - (1.f - bot.m) * (1.f - top.m));
shun-iwasawa 481b59
}
shun-iwasawa 481b59
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
}
shun-iwasawa 481b59
shun-iwasawa 481b59
template <>
shun-iwasawa 481b59
inline TPixelF quickOverPixPremultT<tpixelf, float="">(const TPixelF &bot,</tpixelf,>
shun-iwasawa 481b59
                                                    const TPixelF &top) {
shun-iwasawa 481b59
  float r = top.r * top.m + bot.r * (1.f - top.m);
shun-iwasawa 481b59
  float g = top.g * top.m + bot.g * (1.f - top.m);
shun-iwasawa 481b59
  float b = top.b * top.m + bot.b * (1.f - top.m);
shun-iwasawa 481b59
  return TPixelF(r, g, b,
shun-iwasawa 481b59
                 (bot.m == 1.f) ? 1.f : 1.f - (1.f - bot.m) * (1.f - top.m));
shun-iwasawa 481b59
}
shun-iwasawa 481b59
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
shun-iwasawa 481b59
inline TPixelF overPix(const TPixelF &bot, const TPixelF &top) {
shun-iwasawa 481b59
  return overPixT<tpixelf, float="">(bot, top);</tpixelf,>
shun-iwasawa 481b59
}
shun-iwasawa 481b59
shun-iwasawa 481b59
//-----------------------------------------------------------------------------
shun-iwasawa 481b59
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
shun-iwasawa 215a5b
inline TPixel64 quickOverPixPremult(const TPixel64 &bot, const TPixel64 &top) {
shun-iwasawa 215a5b
  return quickOverPixPremultT<tpixel64, ushort="">(bot, top);</tpixel64,>
shun-iwasawa 215a5b
}
shun-iwasawa 215a5b
shun-iwasawa 215a5b
//-----------------------------------------------------------------------------
shun-iwasawa 215a5b
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
shun-iwasawa 481b59
//-----------------------------------------------------------------------------
shun-iwasawa 481b59
shun-iwasawa 481b59
inline TPixelF quickOverPixPremult(const TPixelF &bot, const TPixelF &top) {
shun-iwasawa 481b59
  return quickOverPixPremultT<tpixelf, float="">(bot, top);</tpixelf,>
shun-iwasawa 481b59
}
shun-iwasawa 481b59
shun-iwasawa 481b59
//-----------------------------------------------------------------------------
shun-iwasawa 481b59
shun-iwasawa 481b59
inline TPixelF quickOverPix(const TPixelF &bot, const TPixelF &top) {
shun-iwasawa 481b59
  return quickOverPixT<tpixelf, float="">(bot, top);</tpixelf,>
shun-iwasawa 481b59
}
shun-iwasawa 481b59
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
shun-iwasawa 481b59
template <>
shun-iwasawa 481b59
inline void overPix<tpixelf, float="">(TPixelF &outPix, const TPixelF &bot,</tpixelf,>
shun-iwasawa 481b59
                                    const TPixelF &top) {
shun-iwasawa 481b59
  if (top.m >= 1.f)
shun-iwasawa 481b59
    outPix = top;
shun-iwasawa 481b59
  else if (top.m <= 0.f)
shun-iwasawa 481b59
    outPix = bot;
shun-iwasawa 481b59
  else {
shun-iwasawa 481b59
    outPix.r = top.r + bot.r * (1.f - top.m);
shun-iwasawa 481b59
    outPix.g = top.g + bot.g * (1.f - top.m);
shun-iwasawa 481b59
    outPix.b = top.b + bot.b * (1.f - top.m);
shun-iwasawa 481b59
    outPix.m = (bot.m >= 1.f) ? bot.m : 1.f - (1.f - bot.m) * (1.f - top.m);
shun-iwasawa 481b59
  }
shun-iwasawa 481b59
}
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.
shun-iwasawa 215a5b
 */
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) {
shun-iwasawa 443318
  pix.r = (typename TPixel64::Channel)((double)pix.r * (double)pix.m / 65535.0);
shun-iwasawa 443318
  pix.g = (typename TPixel64::Channel)((double)pix.g * (double)pix.m / 65535.0);
shun-iwasawa 443318
  pix.b = (typename TPixel64::Channel)((double)pix.b * (double)pix.m / 65535.0);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
shun-iwasawa 481b59
inline void premult(TPixelF &pix) {
shun-iwasawa 481b59
  pix.r = pix.r * pix.m;
shun-iwasawa 481b59
  pix.g = pix.g * pix.m;
shun-iwasawa 481b59
  pix.b = pix.b * pix.m;
shun-iwasawa 481b59
}
shun-iwasawa 481b59
2fc36c
inline void depremult(TPixel32 &pix) {
shun-iwasawa 443318
  float fac = 255.f / (float)pix.m;
shun-iwasawa 443318
  pix.r     = (typename TPixel32::Channel)(std::min((float)pix.r * fac, 255.f));
shun-iwasawa 443318
  pix.g     = (typename TPixel32::Channel)(std::min((float)pix.g * fac, 255.f));
shun-iwasawa 443318
  pix.b     = (typename TPixel32::Channel)(std::min((float)pix.b * fac, 255.f));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
2fc36c
inline void depremult(TPixel64 &pix) {
shun-iwasawa 443318
  double fac = 65535. / (double)pix.m;
shun-iwasawa 443318
  pix.r = (typename TPixel64::Channel)(std::min((double)pix.r * fac, 65535.));
shun-iwasawa 443318
  pix.g = (typename TPixel64::Channel)(std::min((double)pix.g * fac, 65535.));
shun-iwasawa 443318
  pix.b = (typename TPixel64::Channel)(std::min((double)pix.b * fac, 65535.));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
shun-iwasawa 481b59
inline void depremult(TPixelF &pix) {
shun-iwasawa 481b59
  pix.r = pix.r / pix.m;
shun-iwasawa 481b59
  pix.g = pix.g / pix.m;
shun-iwasawa 481b59
  pix.b = pix.b / pix.m;
shun-iwasawa 481b59
}
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) {
shun-iwasawa 443318
  return TPixel64((int)((double)pix.r * (double)pix.m / 65535.),
shun-iwasawa 443318
                  (int)((double)pix.g * (double)pix.m / 65535.),
shun-iwasawa 443318
                  (int)((double)pix.b * (double)pix.m / 65535.), pix.m);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
shun-iwasawa 481b59
inline TPixelF premultiply(const TPixelF &pix) {
shun-iwasawa 481b59
  if (pix.m <= 0.f) return TPixelF(0.f, 0.f, 0.f, 0.f);
shun-iwasawa 481b59
  return TPixelF(pix.r * pix.m, pix.g * pix.m, pix.b * pix.m, pix.m);
shun-iwasawa 481b59
}
shun-iwasawa 481b59
2fc36c
inline TPixel32 depremultiply(const TPixel32 &pix) {
shun-iwasawa 443318
  return TPixel32((int)((double)pix.r * 255. / (double)pix.m),
shun-iwasawa 443318
                  (int)((double)pix.g * 255. / (double)pix.m),
shun-iwasawa 443318
                  (int)((double)pix.b * 255. / (double)pix.m), pix.m);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
2fc36c
inline TPixel64 depremultiply(const TPixel64 &pix) {
shun-iwasawa 443318
  return TPixel64((int)((double)pix.r * 65535. / (double)pix.m),
shun-iwasawa 443318
                  (int)((double)pix.g * 65535. / (double)pix.m),
shun-iwasawa 443318
                  (int)((double)pix.b * 65535. / (double)pix.m), pix.m);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
shun-iwasawa 481b59
inline TPixelF depremultiply(const TPixelF &pix) {
shun-iwasawa 481b59
  if (pix.m <= 0.f) return TPixelF();
shun-iwasawa 481b59
  return TPixelF(pix.r / pix.m, pix.g / pix.m, pix.b / pix.m, pix.m);
shun-iwasawa 481b59
}
shun-iwasawa 481b59
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 &);
shun-iwasawa 481b59
DVAPI TPixel32 toPixel32(const TPixelF &);
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 &);
shun-iwasawa 481b59
DVAPI TPixel64 toPixel64(const TPixelF &);
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 &);
shun-iwasawa 481b59
DVAPI TPixelD toPixelD(const TPixelF &);
shun-iwasawa 481b59
shun-iwasawa 481b59
DVAPI TPixelF toPixelF(const TPixel32 &);
shun-iwasawa 481b59
DVAPI TPixelF toPixelF(const TPixelD &);
shun-iwasawa 481b59
DVAPI TPixelF toPixelF(const TPixel64 &);
shun-iwasawa 481b59
DVAPI TPixelF toPixelF(const TPixelGR8 &);
shun-iwasawa 481b59
shun-iwasawa 481b59
DVAPI TPixel32 toLinear(const TPixel32 &, const double);
shun-iwasawa 481b59
DVAPI TPixel64 toLinear(const TPixel64 &, const double);
shun-iwasawa 481b59
DVAPI TPixelD toLinear(const TPixelD &, const double);
shun-iwasawa 481b59
DVAPI TPixelF toLinear(const TPixelF &, const double);
shun-iwasawa 481b59
DVAPI TPixelGR8 toLinear(const TPixelGR8 &, const double);
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);
shun-iwasawa 481b59
  inline static T from(const TPixelF &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); }
shun-iwasawa 481b59
  inline static TPixel32 from(const TPixelF &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); }
shun-iwasawa 481b59
  inline static TPixel64 from(const TPixelF &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); }
shun-iwasawa 481b59
  inline static TPixelD from(const TPixelF &pix) { return toPixelD(pix); }
shun-iwasawa 481b59
};
shun-iwasawa 481b59
shun-iwasawa 481b59
template <>
shun-iwasawa 481b59
class PixelConverter<tpixelf> {</tpixelf>
shun-iwasawa 481b59
public:
shun-iwasawa 481b59
  inline static TPixelF from(const TPixel32 &pix) { return toPixelF(pix); }
shun-iwasawa 481b59
  inline static TPixelF from(const TPixel64 &pix) { return toPixelF(pix); }
shun-iwasawa 481b59
  inline static TPixelF from(const TPixelD &pix) { return toPixelF(pix); }
shun-iwasawa 481b59
  inline static TPixelF from(const TPixelGR8 &pix) { return toPixelF(pix); }
shun-iwasawa 481b59
  inline static TPixelF from(const TPixelF &pix) { return 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;
shun-iwasawa 215a5b
  r        = pixin.r + v;
shun-iwasawa 215a5b
  g        = pixin.g + v;
shun-iwasawa 215a5b
  b        = pixin.b + v;
shun-iwasawa 215a5b
  m        = pixin.m + v;
shun-iwasawa 215a5b
  pixout.r = (r < 0)
shun-iwasawa 215a5b
                 ? 0
shun-iwasawa 215a5b
                 : ((r < T::maxChannelValue)
shun-iwasawa 215a5b
                        ? troundp(r * (pixout.r / (double)T::maxChannelValue))
shun-iwasawa 215a5b
                        : pixout.r);
shun-iwasawa 215a5b
  pixout.g = (g < 0)
shun-iwasawa 215a5b
                 ? 0
shun-iwasawa 215a5b
                 : ((g < T::maxChannelValue)
shun-iwasawa 215a5b
                        ? troundp(g * (pixout.g / (double)T::maxChannelValue))
shun-iwasawa 215a5b
                        : pixout.g);
shun-iwasawa 215a5b
  pixout.b = (b < 0)
shun-iwasawa 215a5b
                 ? 0
shun-iwasawa 215a5b
                 : ((b < T::maxChannelValue)
shun-iwasawa 215a5b
                        ? troundp(b * (pixout.b / (double)T::maxChannelValue))
shun-iwasawa 215a5b
                        : pixout.b);
shun-iwasawa 215a5b
  pixout.m = (m < 0)
shun-iwasawa 215a5b
                 ? 0
shun-iwasawa 215a5b
                 : ((m < T::maxChannelValue)
shun-iwasawa 215a5b
                        ? troundp(m * (pixout.m / (double)T::maxChannelValue))
shun-iwasawa 215a5b
                        : 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