#include #include #include /* std::numeric_limits */ #include "igs_ifx_common.h" #include "igs_warp.h" namespace { template void hori_change_template_(ST *image, const int height, const int width, const int channels , const RT *refer // same as height,width,channels , const int refchannels, const int refcc , const double offset, const double maxlen, const bool alpha_rendering_sw, const bool anti_aliasing_sw) { const double smax = std::numeric_limits::max(); const double rmax = std::numeric_limits::max(); std::vector> buf_s1(channels), buf_s2(channels); for (int zz = 0; zz < channels; ++zz) { buf_s1.at(zz).resize(width); buf_s2.at(zz).resize(width); } std::vector buf_r(width); refer += refcc; /* 参照画像の参照色チャンネル */ for (int yy = 0; yy < height; ++yy, image += channels * width, refer += refchannels * width) { for (int xx = 0; xx < width; ++xx) { for (int zz = 0; zz < channels; ++zz) { buf_s1.at(zz).at(xx) = image[xx * channels + zz] / smax; } } for (int xx = 0; xx < width; ++xx) { // reference red of refer[] double pos = static_cast(refer[xx * refchannels]); buf_r.at(xx) = ((pos / rmax) - offset) * maxlen; } if (anti_aliasing_sw) { for (int xx = 0; xx < width; ++xx) { double pos = buf_r.at(xx); int fl_pos = xx + static_cast(std::floor(pos)); int ce_pos = xx + static_cast(std::ceil(pos)); double div = pos - floor(pos); if (fl_pos < 0) { fl_pos = 0; } else if (width <= fl_pos) { fl_pos = width - 1; } if (ce_pos < 0) { ce_pos = 0; } else if (width <= ce_pos) { ce_pos = width - 1; } for (int zz = 0; zz < channels; ++zz) { if (!alpha_rendering_sw && (igs::image::rgba::alp == zz)) { buf_s2.at(zz).at(xx) = buf_s1.at(zz).at(xx); } else { buf_s2.at(zz).at(xx) = buf_s1.at(zz).at(fl_pos) * (1.0 - div) + buf_s1.at(zz).at(ce_pos) * div; } } } } else { for (int xx = 0; xx < width; ++xx) { int pos = xx + static_cast(floor(buf_r.at(xx) + 0.5)); if (pos < 0) { pos = 0; } else if (width <= pos) { pos = width - 1; } for (int zz = 0; zz < channels; ++zz) { if (!alpha_rendering_sw && (igs::image::rgba::alp == zz)) { buf_s2.at(zz).at(xx) = buf_s1.at(zz).at(xx); } else { buf_s2.at(zz).at(xx) = buf_s1.at(zz).at(pos); } } } } for (int xx = 0; xx < width; ++xx) { for (int zz = 0; zz < channels; ++zz) { image[xx * channels + zz] = static_cast(buf_s2.at(zz).at(xx) * (smax + 0.999999)); } } } } } //-------------------------------------------------------------------- void igs::warp::hori_change( unsigned char *image, const int height, const int width, const int channels, const int bits , const unsigned char *refer // by height,width,channels , const int refchannels, const int refcc, const int refbit , const double offset, const double maxlen, const bool alpha_rendering_sw, const bool anti_aliasing_sw) { const int ucharb = std::numeric_limits::digits; const int ushortb = std::numeric_limits::digits; if ((ushortb == bits) && (ushortb == refbit)) { hori_change_template_( reinterpret_cast(image), height, width, channels, reinterpret_cast(refer), refchannels, refcc, offset, maxlen, alpha_rendering_sw, anti_aliasing_sw); } else if ((ushortb == bits) && (ucharb == refbit)) { hori_change_template_(reinterpret_cast(image), height, width, channels, refer, refchannels, refcc, offset, maxlen, alpha_rendering_sw, anti_aliasing_sw); } else if ((ucharb == bits) && (ushortb == refbit)) { hori_change_template_(image, height, width, channels, reinterpret_cast(refer), refchannels, refcc, offset, maxlen, alpha_rendering_sw, anti_aliasing_sw); } else if ((ucharb == bits) && (ucharb == refbit)) { hori_change_template_(image, height, width, channels, refer, refchannels, refcc, offset, maxlen, alpha_rendering_sw, anti_aliasing_sw); } }