Toshihiro Shimizu 890ddd
#include "igs_density.h"
shun-iwasawa 481b59
#include <iostream></iostream>
Shinya Kitaoka 120a6e
namespace {
shun-iwasawa 481b59
float accum_by_trans_(const float src_value /* 元値(R,G,B) */
shun-iwasawa 481b59
                      ,
shun-iwasawa 481b59
                      const float transparent /* src_valueの透明度(0...1) */
shun-iwasawa 481b59
                      ,
shun-iwasawa 481b59
                      const int integer_part /* 濃度値の整数部分(0...) */
shun-iwasawa 481b59
                      ,
shun-iwasawa 481b59
                      const double fractional_part /* 濃度値の少数部分(0...1) */
shun-iwasawa 481b59
) {
shun-iwasawa 481b59
  float accumulation = src_value;
Shinya Kitaoka 120a6e
  if (1 <= integer_part) {
Shinya Kitaoka 120a6e
    for (int ii = 1; ii < integer_part; ++ii) {
Shinya Kitaoka 120a6e
      accumulation = accumulation * transparent + src_value;
Shinya Kitaoka 120a6e
    }
shun-iwasawa 481b59
    if (0.f < fractional_part) {
Shinya Kitaoka 120a6e
      accumulation +=
Shinya Kitaoka 120a6e
          ((accumulation * transparent + src_value) - accumulation) *
Shinya Kitaoka 120a6e
          fractional_part;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else { /* 整数部分がゼロ以下のとき */
shun-iwasawa 481b59
    if (0.f < fractional_part) {
Shinya Kitaoka 120a6e
      accumulation *= fractional_part;
Shinya Kitaoka 120a6e
    } else { /* 少数部分もゼロ以下のとき */
shun-iwasawa 481b59
      accumulation = 0.f;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
shun-iwasawa 481b59
  return (1.f < accumulation) ? 1.f
shun-iwasawa 481b59
                              : ((accumulation < 0.f) ? 0.f : accumulation);
Toshihiro Shimizu 890ddd
}
shun-iwasawa 481b59
}  // namespace
Shinya Kitaoka 120a6e
#include <limits>           /* std::numeric_limits */</limits>
Toshihiro Shimizu 890ddd
#include "igs_ifx_common.h" /* igs::image::rgba */
Shinya Kitaoka 120a6e
namespace {
shun-iwasawa 481b59
void change_(float *image_array, const int height, const int width,
shun-iwasawa 481b59
             const int channels, const float *ref, const double density) {
Shinya Kitaoka 120a6e
  const int integer_part       = (int)density;
Shinya Kitaoka 120a6e
  const double fractional_part = density - (int)density;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  using namespace igs::image::rgba;
Shinya Kitaoka 120a6e
  const int pixsize = height * width;
Shinya Kitaoka 120a6e
  for (int ii = 0; ii < pixsize; ++ii, image_array += channels) {
shun-iwasawa 481b59
    const float rr1 = image_array[red];
shun-iwasawa 481b59
    const float gg1 = image_array[gre];
shun-iwasawa 481b59
    const float bb1 = image_array[blu];
shun-iwasawa 481b59
    const float aa1 = image_array[alp];
Toshihiro Shimizu 890ddd
shun-iwasawa 481b59
    float rr2 = accum_by_trans_(rr1, 1.0 - aa1, integer_part, fractional_part);
shun-iwasawa 481b59
    float gg2 = accum_by_trans_(gg1, 1.0 - aa1, integer_part, fractional_part);
shun-iwasawa 481b59
    float bb2 = accum_by_trans_(bb1, 1.0 - aa1, integer_part, fractional_part);
shun-iwasawa 481b59
    float aa2 = accum_by_trans_(aa1, 1.0 - aa1, integer_part, fractional_part);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    /* 参照画像あればピクセル単位の画像変化 */
shun-iwasawa 481b59
    if (ref != nullptr) {
shun-iwasawa 481b59
      rr2 = (rr2 - rr1) * (*ref) + rr1;
shun-iwasawa 481b59
      gg2 = (gg2 - gg1) * (*ref) + gg1;
shun-iwasawa 481b59
      bb2 = (bb2 - bb1) * (*ref) + bb1;
shun-iwasawa 481b59
      aa2 = (aa2 - aa1) * (*ref) + aa1;
shun-iwasawa 481b59
      ref++;
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
shun-iwasawa 481b59
    image_array[red] = rr2;
shun-iwasawa 481b59
    image_array[gre] = gg2;
shun-iwasawa 481b59
    image_array[blu] = bb2;
shun-iwasawa 481b59
    image_array[alp] = aa2;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
shun-iwasawa 481b59
}  // namespace
Toshihiro Shimizu 890ddd
#include <stdexcept> /* std::domain_error(-) */</stdexcept>
shun-iwasawa 481b59
void igs::density::change(float *image_array, const int height, const int width,
shun-iwasawa 481b59
                          const int channels, /* 4(=RGBAでなければならない) */
shun-iwasawa 481b59
                          const float *ref, const double density) {
Shinya Kitaoka 120a6e
  if (igs::image::rgba::siz != channels) {
Shinya Kitaoka 120a6e
    throw std::domain_error("Bad channels,Not rgba");
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
shun-iwasawa 481b59
  change_(image_array, height, width, channels, ref, density);
Toshihiro Shimizu 890ddd
}