Shinya Kitaoka 120a6e
#include <cmath>  // pow()</cmath>
Toshihiro Shimizu 890ddd
#include "iwa_noise1234.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Shinya Kitaoka 120a6e
double perlin_noise_3d_(const double x, const double y, const double z,
Shinya Kitaoka 120a6e
                        const int octaves_start  // 0<=
Shinya Kitaoka 120a6e
                        ,
Shinya Kitaoka 120a6e
                        const int octaves_end  // 0<=
Shinya Kitaoka 120a6e
                        ,
Shinya Kitaoka 120a6e
                        const double persistence  // Not 0
Shinya Kitaoka 120a6e
                        // 1/4 or 1/2 or 1/sqrt(3) or 1/sqrt(2) or 1 or ...
shun-iwasawa 0a07c8
) {
Shinya Kitaoka 120a6e
  double total = 0;
Shinya Kitaoka 120a6e
  Noise1234 pn;
Shinya Kitaoka 120a6e
  for (int ii = octaves_start; ii <= octaves_end; ++ii) {
Shinya Kitaoka 120a6e
    const double frequency = pow(2.0, ii);  // 1,2,4,8...
Shinya Kitaoka 120a6e
    const double amplitude = pow(persistence, ii);
Shinya Kitaoka 120a6e
    total += pn.noise(x * frequency, y * frequency, z * frequency) * amplitude;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return total;
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 120a6e
double perlin_noise_minmax_(const int octaves_start  // 0<=
Shinya Kitaoka 120a6e
                            ,
Shinya Kitaoka 120a6e
                            const int octaves_end  // 0<=
Shinya Kitaoka 120a6e
                            ,
Shinya Kitaoka 120a6e
                            const double persistence  // Not 0
Shinya Kitaoka 120a6e
                            // 1/4 or 1/2 or 1/sqrt(3) or 1/sqrt(2) or 1 or ...
shun-iwasawa 0a07c8
) {
Shinya Kitaoka 120a6e
  double total = 0;
Shinya Kitaoka 120a6e
  for (int ii = octaves_start; ii <= octaves_end; ++ii) {
Shinya Kitaoka 120a6e
    total += pow(persistence, ii);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return total;
Toshihiro Shimizu 890ddd
}
shun-iwasawa 0a07c8
}  // namespace
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------
Shinya Kitaoka 120a6e
#include <stdexcept>        // std::domain_error(-)</stdexcept>
Shinya Kitaoka 120a6e
#include <limits>           // std::numeric_limits</limits>
Toshihiro Shimizu 890ddd
#include "igs_ifx_common.h" /* igs::image::rgba */
Toshihiro Shimizu 890ddd
#include "igs_perlin_noise.h"
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
template <class t=""></class>
shun-iwasawa 0a07c8
void change_(T *image_array, const int height, const int width,
shun-iwasawa 0a07c8
             const int wrap,  // pixel
Shinya Kitaoka 120a6e
             const int channels, const bool alpha_rendering_sw,
Shinya Kitaoka 120a6e
             const double a11  // geometry of 2D affine transformation
Shinya Kitaoka 120a6e
             ,
Shinya Kitaoka 120a6e
             const double a12, const double a13, const double a21,
Shinya Kitaoka 120a6e
             const double a22, const double a23, const double zz,
Shinya Kitaoka 120a6e
             const int octaves_start  // 0<=
Shinya Kitaoka 120a6e
             ,
Shinya Kitaoka 120a6e
             const int octaves_end  // 0<=
Shinya Kitaoka 120a6e
             ,
Shinya Kitaoka 120a6e
             const double persistence  // Not 0
shun-iwasawa 0a07c8
) {
Shinya Kitaoka 120a6e
  const int max_div   = std::numeric_limits<t>::max();</t>
Shinya Kitaoka 120a6e
  const int max_div_2 = max_div / 2;
Shinya Kitaoka 120a6e
  // 255 / 2    --> 127
Shinya Kitaoka 120a6e
  // 65535 / 2  --> 32767
Shinya Kitaoka 120a6e
  // const double max_mul = static_cast<double>(max_div_2+0.999999);</double>
Shinya Kitaoka 120a6e
  // const double max_off = static_cast<double>(max_div_2+1);</double>
Shinya Kitaoka 120a6e
  const double max_mul = static_cast<double>(max_div_2 + 0.499999);</double>
Shinya Kitaoka 120a6e
  const double max_off = static_cast<double>(max_div_2 + 1.5);</double>
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
  -1 .............. 0 ......... 1
Shinya Kitaoka 120a6e
  x127+0.499999
Shinya Kitaoka 120a6e
  ------------------------------------------
Shinya Kitaoka 120a6e
  -127+0.499999 ... 0 ......... 127+0.499999
Shinya Kitaoka 120a6e
  +127+1.5      ... 127+1.5 ... 127+1.5
Shinya Kitaoka 120a6e
  ------------------------------------------
Shinya Kitaoka 120a6e
  1.000001 ........ 127+1.5 ... 255.999999
Shinya Kitaoka 120a6e
  integer
Shinya Kitaoka 120a6e
  ------------------------------------------
Shinya Kitaoka 120a6e
  1 ............... 128 ....... 255
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  const double maxi =
Shinya Kitaoka 120a6e
      perlin_noise_minmax_(octaves_start, octaves_end, persistence);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  using namespace igs::image::rgba;
shun-iwasawa 0a07c8
  T *image_crnt;
shun-iwasawa 0a07c8
  T *image_scanline = image_array;
Shinya Kitaoka 120a6e
  for (int yy = 0; yy < height; ++yy) {
shun-iwasawa 0a07c8
    image_crnt = image_scanline;
Shinya Kitaoka 120a6e
    for (int xx = 0; xx < width; ++xx, image_crnt += channels) {
Shinya Kitaoka 120a6e
      const T val = static_cast<t>(</t>
Shinya Kitaoka 120a6e
          perlin_noise_3d_(xx * a11 + yy * a12 + a13, xx * a21 + yy * a22 + a23,
Shinya Kitaoka 120a6e
                           zz, octaves_start, octaves_end, persistence) /
Shinya Kitaoka 120a6e
              maxi * max_mul +
Shinya Kitaoka 120a6e
          max_off);
Shinya Kitaoka 120a6e
      for (int zz = 0; zz < channels; ++zz) {
Shinya Kitaoka 120a6e
        if (!alpha_rendering_sw && (alp == zz)) {
Shinya Kitaoka 120a6e
          image_crnt[zz] = static_cast<t>(max_div);</t>
Shinya Kitaoka 120a6e
        } else {
Shinya Kitaoka 120a6e
          image_crnt[zz] = val;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
shun-iwasawa 0a07c8
    image_scanline += channels * wrap;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
shun-iwasawa 481b59
template <>
shun-iwasawa 481b59
void change_(float *image_array, const int height, const int width,
shun-iwasawa 481b59
             const int wrap,  // pixel
shun-iwasawa 481b59
             const int channels, const bool alpha_rendering_sw,
shun-iwasawa 481b59
             const double a11  // geometry of 2D affine transformation
shun-iwasawa 481b59
             ,
shun-iwasawa 481b59
             const double a12, const double a13, const double a21,
shun-iwasawa 481b59
             const double a22, const double a23, const double zz,
shun-iwasawa 481b59
             const int octaves_start  // 0<=
shun-iwasawa 481b59
             ,
shun-iwasawa 481b59
             const int octaves_end  // 0<=
shun-iwasawa 481b59
             ,
shun-iwasawa 481b59
             const double persistence  // Not 0
shun-iwasawa 481b59
) {
shun-iwasawa 481b59
  const float max_div   = 1.f;
shun-iwasawa 481b59
  const float max_div_2 = 0.5f;
shun-iwasawa 481b59
shun-iwasawa 481b59
  const double maxi =
shun-iwasawa 481b59
      perlin_noise_minmax_(octaves_start, octaves_end, persistence);
shun-iwasawa 481b59
shun-iwasawa 481b59
  using namespace igs::image::rgba;
shun-iwasawa 481b59
  float *image_crnt;
shun-iwasawa 481b59
  float *image_scanline = image_array;
shun-iwasawa 481b59
  for (int yy = 0; yy < height; ++yy) {
shun-iwasawa 481b59
    image_crnt = image_scanline;
shun-iwasawa 481b59
    for (int xx = 0; xx < width; ++xx, image_crnt += channels) {
shun-iwasawa 481b59
      const float val = static_cast<float>(</float>
shun-iwasawa 481b59
          perlin_noise_3d_(xx * a11 + yy * a12 + a13, xx * a21 + yy * a22 + a23,
shun-iwasawa 481b59
                           zz, octaves_start, octaves_end, persistence) /
shun-iwasawa 481b59
              maxi * 0.5f +
shun-iwasawa 481b59
          0.5f);
shun-iwasawa 481b59
      for (int zz = 0; zz < channels; ++zz) {
shun-iwasawa 481b59
        if (!alpha_rendering_sw && (alp == zz)) {
shun-iwasawa 481b59
          image_crnt[zz] = 1.f;
shun-iwasawa 481b59
        } else {
shun-iwasawa 481b59
          image_crnt[zz] = val;
shun-iwasawa 481b59
        }
shun-iwasawa 481b59
      }
shun-iwasawa 481b59
    }
shun-iwasawa 481b59
    image_scanline += channels * wrap;
shun-iwasawa 481b59
  }
shun-iwasawa 481b59
}
shun-iwasawa 481b59
shun-iwasawa 0a07c8
}  // namespace
Toshihiro Shimizu 890ddd
// #include "igs_geometry2d.h"
Toshihiro Shimizu 890ddd
void igs::perlin_noise::change(
shun-iwasawa 0a07c8
    unsigned char *image_array, const int height, const int width,
shun-iwasawa 0a07c8
    const int wrap,  // pixel
Shinya Kitaoka 120a6e
    const int channels, const int bits, const bool alpha_rendering_sw,
Shinya Kitaoka 120a6e
    const double a11  // geometry of 2D affine transformation
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const double a12, const double a13, const double a21, const double a22,
Shinya Kitaoka 120a6e
    const double a23, const double zz, const int octaves_start  // 0...
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const int octaves_end  // 0...
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const double persistence  // not 0
shun-iwasawa 0a07c8
) {
Shinya Kitaoka 120a6e
  // igs::geometry2d::affine af(a11 , a12 , a13 , a21 , a22 , a23);
Shinya Kitaoka 120a6e
  // igs::geometry2d::translate();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (std::numeric_limits<unsigned char="">::digits == bits) {</unsigned>
shun-iwasawa 0a07c8
    change_(image_array, height, width, wrap, channels, alpha_rendering_sw, a11,
shun-iwasawa 0a07c8
            a12, a13, a21, a22, a23, zz, octaves_start, octaves_end,
shun-iwasawa 0a07c8
            persistence);
Shinya Kitaoka 120a6e
  } else if (std::numeric_limits<unsigned short="">::digits == bits) {</unsigned>
Shinya Kitaoka 120a6e
    change_(reinterpret_cast<unsigned *="" short="">(image_array), height, width,</unsigned>
shun-iwasawa 0a07c8
            wrap, channels, alpha_rendering_sw, a11, a12, a13, a21, a22, a23,
shun-iwasawa 0a07c8
            zz, octaves_start, octaves_end, persistence);
shun-iwasawa 481b59
  } else if (std::numeric_limits<float>::digits == bits) {</float>
shun-iwasawa 481b59
    change_(reinterpret_cast<float *="">(image_array), height, width, wrap,</float>
shun-iwasawa 481b59
            channels, alpha_rendering_sw, a11, a12, a13, a21, a22, a23, zz,
shun-iwasawa 481b59
            octaves_start, octaves_end, persistence);
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    throw std::domain_error("Bad bits,Not uchar/ushort");
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}