Shinya Kitaoka 79e39b
#include <memory></memory>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// SDirection.cpp: implementation of the CSDirection class.
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//////////////////////////////////////////////////////////////////////
Toshihiro Shimizu 890ddd
#include <stdlib.h></stdlib.h>
Toshihiro Shimizu 890ddd
#include <memory.h></memory.h>
Michał Janiszewski a6309b
#include <algorithm></algorithm>
Toshihiro Shimizu 890ddd
#include "SDirection.h"
Toshihiro Shimizu 890ddd
#include "SError.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//////////////////////////////////////////////////////////////////////
Toshihiro Shimizu 890ddd
// Construction/Destruction
Toshihiro Shimizu 890ddd
//////////////////////////////////////////////////////////////////////
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
CSDirection::CSDirection() : m_lX(0), m_lY(0), m_lDf(0) {
Shinya Kitaoka 120a6e
  for (int i = 0; i < NBDIR; i++) m_df[i] = 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
CSDirection::CSDirection(const int lX, const int lY, const UCHAR *sel,
Shinya Kitaoka 120a6e
                         const int sens)
Shinya Kitaoka 120a6e
    : m_lX(lX), m_lY(lY), m_lDf(0) {
Shinya Kitaoka 120a6e
  for (int i = 0; i < NBDIR; i++) m_df[i] = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    if (m_lX > 0 && m_lY > 0) {
Shinya Kitaoka 120a6e
      m_dir.reset(new UCHAR[m_lX * m_lY]);
Shinya Kitaoka 120a6e
      if (!m_dir) {
Shinya Kitaoka 120a6e
        null();
Shinya Kitaoka 120a6e
        throw SMemAllocError("in directionMap");
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      memcpy(m_dir.get(), sel, sizeof(UCHAR) * m_lX * m_lY);
Shinya Kitaoka 120a6e
      setDir01();
Shinya Kitaoka 120a6e
      //			For optimalization purpose.
Shinya Kitaoka 120a6e
      //			The quality is better, if it is removed.
Shinya Kitaoka 120a6e
      //			setContourBorder(2);
Shinya Kitaoka 120a6e
      makeDirFilter(sens);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } catch (SMemAllocError) {
Shinya Kitaoka 120a6e
    throw;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
CSDirection::CSDirection(const int lX, const int lY, const UCHAR *sel,
Shinya Kitaoka 120a6e
                         const int sens, const int border)
Shinya Kitaoka 120a6e
    : m_lX(lX), m_lY(lY), m_lDf(0) {
Shinya Kitaoka 120a6e
  for (int i = 0; i < NBDIR; i++) m_df[i] = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    if (m_lX > 0 && m_lY > 0) {
Shinya Kitaoka 120a6e
      m_dir.reset(new UCHAR[m_lX * m_lY]);
Shinya Kitaoka 120a6e
      if (!m_dir) {
Shinya Kitaoka 120a6e
        null();
Shinya Kitaoka 120a6e
        throw SMemAllocError("in directionMap");
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      memcpy(m_dir.get(), sel, sizeof(UCHAR) * m_lX * m_lY);
Shinya Kitaoka 120a6e
      setDir01();
Shinya Kitaoka 120a6e
      if (border > 0) setContourBorder(border);
Shinya Kitaoka 120a6e
      makeDirFilter(sens);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } catch (SMemAllocError) {
Shinya Kitaoka 120a6e
    throw;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool CSDirection::isContourBorder(const int xx, const int yy,
Shinya Kitaoka 120a6e
                                  const int border) {
Shinya Kitaoka 120a6e
  for (int y = yy - border; y <= (yy + border); y++)
Shinya Kitaoka 120a6e
    for (int x = xx - border; x <= (xx + border); x++)
Shinya Kitaoka 120a6e
      if (x >= 0 && y >= 0 && x < m_lX && y < m_lY)
Shinya Kitaoka 120a6e
        if (*(m_dir.get() + y * m_lX + x) == (UCHAR)0) return true;
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void CSDirection::setContourBorder(const int border) {
Shinya Kitaoka 120a6e
  UCHAR *pDir = m_dir.get();
Shinya Kitaoka 120a6e
  int y       = 0;
Shinya Kitaoka 120a6e
  for (y = 0; y < m_lY; y++)
Shinya Kitaoka 120a6e
    for (int x = 0; x < m_lX; x++, pDir++)
Shinya Kitaoka 120a6e
      if (*pDir == (UCHAR)1)
Shinya Kitaoka 120a6e
        if (!isContourBorder(x, y, border)) *pDir = (UCHAR)2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int xy = m_lX * m_lY;
Shinya Kitaoka 120a6e
  pDir   = m_dir.get();
Shinya Kitaoka 120a6e
  for (y = 0; y < xy; y++, pDir++) *pDir = *pDir == (UCHAR)2 ? (UCHAR)0 : *pDir;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void CSDirection::null() {
Shinya Kitaoka 120a6e
  m_dir.reset();
Shinya Kitaoka 120a6e
  for (auto &&df : m_df) {
Shinya Kitaoka 120a6e
    df.reset();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  m_lX = m_lY = 0;
Shinya Kitaoka 120a6e
  m_lDf       = 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
CSDirection::~CSDirection() { null(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
double CSDirection::adjustAngle(const short sum[4], const int Ima,
Shinya Kitaoka 120a6e
                                const int Im45, const int Ip45) {
Shinya Kitaoka 120a6e
  short ma = std::max(sum[Im45], sum[Ip45]);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (ma < 0) return 0.0;
Shinya Kitaoka 120a6e
  if ((double)ma < (double)sum[Ima] / 10.0) return 0.0;
Shinya Kitaoka 120a6e
  if (((double)abs(sum[Im45] - sum[Ip45]) / (double)ma) < 0.5) return 0.0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double d = 45.0 * (double)ma / (double)(sum[Ima] + ma);
Shinya Kitaoka 120a6e
  if (ma == sum[Im45]) return -d;
Shinya Kitaoka 120a6e
  return d;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
double CSDirection::getAngle(const short sum[4], short ma) {
Shinya Kitaoka 120a6e
  int nbMax   = ma == sum[0] ? 1 : 0;
Shinya Kitaoka 120a6e
  nbMax       = ma == sum[1] ? nbMax + 1 : nbMax;
Shinya Kitaoka 120a6e
  nbMax       = ma == sum[2] ? nbMax + 1 : nbMax;
Shinya Kitaoka 120a6e
  nbMax       = ma == sum[3] ? nbMax + 1 : nbMax;
Shinya Kitaoka 120a6e
  double diff = 50.0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (nbMax == 1) {
Shinya Kitaoka 120a6e
    double angle, corrAngle;
Shinya Kitaoka 120a6e
    if (ma == sum[0]) {
Shinya Kitaoka 120a6e
      angle                      = 0.0;
Shinya Kitaoka 120a6e
      corrAngle                  = adjustAngle(sum, 0, 3, 1);
Shinya Kitaoka 120a6e
      if (corrAngle < 0.0) angle = 180.0;
Shinya Kitaoka 120a6e
    } else if (ma == sum[1]) {
Shinya Kitaoka 120a6e
      angle     = 45.0;
Shinya Kitaoka 120a6e
      corrAngle = adjustAngle(sum, 1, 0, 2);
Shinya Kitaoka 120a6e
    } else if (ma == sum[2]) {
Shinya Kitaoka 120a6e
      angle     = 90.0;
Shinya Kitaoka 120a6e
      corrAngle = adjustAngle(sum, 2, 1, 3);
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      angle     = 135.0;
Shinya Kitaoka 120a6e
      corrAngle = adjustAngle(sum, 3, 2, 0);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    return angle + corrAngle + diff;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  ///* ?????????????????????? kiprobalni
Shinya Kitaoka 120a6e
  if (nbMax == 2) {
Shinya Kitaoka 120a6e
    if (ma == sum[0] && ma == sum[1]) return 22.5 + diff;
Shinya Kitaoka 120a6e
    if (ma == sum[0] && ma == sum[3]) return 157.5 + diff;
Shinya Kitaoka 120a6e
    if (ma == sum[1] && ma == sum[2]) return 67.5 + diff;
Shinya Kitaoka 120a6e
    if (ma == sum[2] && ma == sum[3]) return 112.5 + diff;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  //*/
Shinya Kitaoka 120a6e
  return 1.0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UCHAR CSDirection::getDir(const int xx, const int yy, UCHAR *sel) {
Shinya Kitaoka 120a6e
  short sum[4] = {0, 0, 0, 0};
Shinya Kitaoka 120a6e
  short w      = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (int i = 0; i < m_lDf; i++) {
Shinya Kitaoka 120a6e
    int x = xx + m_df[0][i].x;
Shinya Kitaoka 120a6e
    int y = yy + m_df[0][i].y;
Shinya Kitaoka 120a6e
    if (y >= 0 && y < m_lY && x >= 0 && x < m_lX) {
Shinya Kitaoka 120a6e
      UCHAR *pSel = sel + y * m_lX + x;
Shinya Kitaoka 120a6e
      for (int j = 0; j < NBDIR; j++) sum[j] += (short)(*pSel) * m_df[j][i].w;
Shinya Kitaoka 120a6e
      w += (short)(*pSel);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (w == 0) return 0;
Michał Janiszewski a6309b
  short ma     = *std::max_element(sum, sum + 4);
Shinya Kitaoka 120a6e
  double angle = getAngle(sum, ma);
Shinya Kitaoka 120a6e
  // tmsg_info(" - dir - %d, %d, %d, %d angle=%f", sum[0],sum[1],sum[2],sum[3],
Shinya Kitaoka 120a6e
  //		                                          angle-50.0);
Shinya Kitaoka 120a6e
  return UC_ROUND(angle);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void CSDirection::makeDir(UCHAR *sel) {
Shinya Kitaoka 120a6e
  UCHAR *pSel = sel;
Shinya Kitaoka 120a6e
  UCHAR *pDir = m_dir.get();
Shinya Kitaoka 120a6e
  for (int y = 0; y < m_lY; y++)
Shinya Kitaoka 120a6e
    for (int x = 0; x < m_lX; x++, pSel++, pDir++) {
Shinya Kitaoka 120a6e
      *pDir                = 0;
Shinya Kitaoka 120a6e
      if (*pSel > 0) *pDir = getDir(x, y, sel);
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UCHAR CSDirection::equalizeDir_GTE50(UCHAR *sel, const int xx, const int yy,
Shinya Kitaoka 120a6e
                                     const int d) {
Shinya Kitaoka 120a6e
  int sum = 0;
Shinya Kitaoka 120a6e
  int w   = 0;
Shinya Kitaoka 120a6e
  int aa;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  aa = (int)*(sel + yy * m_lX + xx) - 50;
Shinya Kitaoka 120a6e
  for (int y = yy - d; y <= (yy + d); y++)
Shinya Kitaoka 120a6e
    for (int x = xx - d; x <= (xx + d); x++)
Shinya Kitaoka 120a6e
      if (x >= 0 && y >= 0 && x < m_lX && y < m_lY) {
Shinya Kitaoka 120a6e
        UCHAR *pSel = sel + y * m_lX + x;
Shinya Kitaoka 120a6e
        int a       = (int)*pSel;
Shinya Kitaoka 120a6e
        if (a >= 50) {
Shinya Kitaoka 120a6e
          a -= 50;
Shinya Kitaoka 120a6e
          if (aa < 90 && a > 135) {
Shinya Kitaoka 120a6e
            a = -(180 - a);
Shinya Kitaoka 120a6e
          } else if (aa > 90 && a < 45) {
Shinya Kitaoka 120a6e
            a = 180 + a;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
          sum += a;
Shinya Kitaoka 120a6e
          w++;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
  if (w > 0) {
Shinya Kitaoka 120a6e
    double q = (double)sum / (double)w;
Shinya Kitaoka 120a6e
    int a    = I_ROUND(q);
Shinya Kitaoka 120a6e
    if (a >= 180) {
Shinya Kitaoka 120a6e
      a -= 180;
Shinya Kitaoka 120a6e
    } else if (a < 0) {
Shinya Kitaoka 120a6e
      a = 180 + a;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    return (UCHAR)(a + 50);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return *(sel + yy * m_lX + xx);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UCHAR CSDirection::equalizeDir_LT50(UCHAR *sel, const int xx, const int yy,
Shinya Kitaoka 120a6e
                                    const int d) {
Shinya Kitaoka 120a6e
  int sum = 0;
Shinya Kitaoka 120a6e
  int w   = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (int y = yy - d; y <= (yy + d); y++)
Shinya Kitaoka 120a6e
    for (int x = xx - d; x <= (xx + d); x++)
Shinya Kitaoka 120a6e
      if (x >= 0 && y >= 0 && x < m_lX && y < m_lY) {
Shinya Kitaoka 120a6e
        int a = (int)*(sel + y * m_lX + x);
Shinya Kitaoka 120a6e
        if (a >= 50) {
Shinya Kitaoka 120a6e
          a -= 50;
Shinya Kitaoka 120a6e
          sum += a;
Shinya Kitaoka 120a6e
          w++;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
  if (w > 0) {
Shinya Kitaoka 120a6e
    double q = (double)sum / (double)w;
Shinya Kitaoka 120a6e
    int a    = I_ROUND(q);
Shinya Kitaoka 120a6e
    if (a >= 180) {
Shinya Kitaoka 120a6e
      a -= 180;
Shinya Kitaoka 120a6e
    } else if (a < 0) {
Shinya Kitaoka 120a6e
      a = 180 + a;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    return (UCHAR)(a + 50);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return *(sel + yy * m_lX + xx);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void CSDirection::equalizeDir(UCHAR *sel, const int d) {
Shinya Kitaoka 120a6e
  UCHAR *pSel = sel;
Shinya Kitaoka 120a6e
  UCHAR *pDir = m_dir.get();
Shinya Kitaoka 120a6e
  for (int y = 0; y < m_lY; y++)
Shinya Kitaoka 120a6e
    for (int x = 0; x < m_lX; x++, pSel++) {
Shinya Kitaoka 120a6e
      if (*pSel > (UCHAR)0) {
Shinya Kitaoka 120a6e
        if (*pSel >= (UCHAR)50)
Shinya Kitaoka 120a6e
          *pDir = equalizeDir_GTE50(sel, x, y, d);
Shinya Kitaoka 120a6e
        else
Shinya Kitaoka 120a6e
          *pDir = equalizeDir_LT50(sel, x, y, d);
Shinya Kitaoka 120a6e
      } else
Shinya Kitaoka 120a6e
        *pDir = (UCHAR)0;
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Campbell Barton b3bd84
static UCHAR getRadius(const double angle, const double r[4]) {
Shinya Kitaoka 120a6e
  double p, q;
Shinya Kitaoka 120a6e
  if (angle >= 0.0 && angle < 45.0) {
Shinya Kitaoka 120a6e
    q = angle / 45.0;
Shinya Kitaoka 120a6e
    p = r[0] * (1.0 - q) + r[1] * q;
Shinya Kitaoka 120a6e
  } else if (angle >= 45.0 && angle < 90.0) {
Shinya Kitaoka 120a6e
    q = (angle - 45.0) / 45.0;
Shinya Kitaoka 120a6e
    p = r[1] * (1.0 - q) + r[2] * q;
Shinya Kitaoka 120a6e
  } else if (angle >= 90.0 && angle < 135.0) {
Shinya Kitaoka 120a6e
    q = (angle - 90.0) / 45.0;
Shinya Kitaoka 120a6e
    p = r[2] * (1.0 - q) + r[3] * q;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    q = (angle - 135.0) / 45.0;
Shinya Kitaoka 120a6e
    p = r[3] * (1.0 - q) + r[0] * q;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return (UCHAR)(1 + I_ROUND(p * 254.0));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void CSDirection::makeDirFilter(const int sens) {
Shinya Kitaoka 120a6e
  const int size   = 2 * sens + 1;
Shinya Kitaoka 120a6e
  const int middle = size / 2;
Shinya Kitaoka 120a6e
  const int maxVal = size - 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_lDf = size * size;
Shinya Kitaoka 120a6e
  for (int i = 0; i < NBDIR; i++) {
Shinya Kitaoka 120a6e
    m_df[i].reset(new SXYW[m_lDf]);
Shinya Kitaoka 120a6e
    if (!m_df[i]) {
Shinya Kitaoka 120a6e
      null();
Shinya Kitaoka 120a6e
      throw SMemAllocError("in directionMap");
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    for (int y = 0; y < size; y++)
Shinya Kitaoka 120a6e
      for (int x = 0; x < size; x++) {
Shinya Kitaoka 120a6e
        int xy        = y * size + x;
Shinya Kitaoka 120a6e
        m_df[i][xy].x = x - middle;
Shinya Kitaoka 120a6e
        m_df[i][xy].y = y - middle;
Shinya Kitaoka 120a6e
        switch (i) {
Shinya Kitaoka 120a6e
        case 0:
Shinya Kitaoka 120a6e
          // Horizontal
Shinya Kitaoka 120a6e
          m_df[i][xy].w = y == middle ? maxVal : -1;
Shinya Kitaoka 120a6e
          break;
Shinya Kitaoka 120a6e
        case 1:
Shinya Kitaoka 120a6e
          // Left - Right
Shinya Kitaoka 120a6e
          m_df[i][xy].w = x == y ? maxVal : -1;
Shinya Kitaoka 120a6e
          break;
Shinya Kitaoka 120a6e
        case 2:
Shinya Kitaoka 120a6e
          // Vertical
Shinya Kitaoka 120a6e
          m_df[i][xy].w = x == middle ? maxVal : -1;
Shinya Kitaoka 120a6e
          break;
Shinya Kitaoka 120a6e
        case 3:
Shinya Kitaoka 120a6e
          // Right - Left
Shinya Kitaoka 120a6e
          m_df[i][xy].w = (x + y) == (size - 1) ? maxVal : -1;
Shinya Kitaoka 120a6e
          break;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UCHAR CSDirection::blurRadius(UCHAR *sel, const int xx, const int yy,
Shinya Kitaoka 120a6e
                              const int dBlur) {
Shinya Kitaoka 120a6e
  int sum, w;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  sum = w = 0;
Shinya Kitaoka 120a6e
  for (int y = yy - dBlur; y <= (yy + dBlur); y++)
Shinya Kitaoka 120a6e
    for (int x = xx - dBlur; x <= (xx + dBlur); x++)
Shinya Kitaoka 120a6e
      if (x >= 0 && y >= 0 && x < m_lX && y < m_lY) {
Shinya Kitaoka 120a6e
        UCHAR *pSel = sel + y * m_lX + x;
Shinya Kitaoka 120a6e
        if (*pSel > (UCHAR)0) {
Shinya Kitaoka 120a6e
          sum += (int)(*pSel);
Shinya Kitaoka 120a6e
          w++;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
  if (w > 0) {
Shinya Kitaoka 120a6e
    double d = (double)sum / (double)w;
Shinya Kitaoka 120a6e
    d        = D_CUT_0_255(d);
Shinya Kitaoka 120a6e
    return UC_ROUND(d);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return *(sel + yy * m_lX + xx);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void CSDirection::blurRadius(const int dBlur) {
Shinya Kitaoka 120a6e
  if (m_lX > 0 && m_lY > 0 && m_dir) {
Shinya Kitaoka 120a6e
    std::unique_ptr<uchar[]> sel(new UCHAR[m_lX * m_lY]);</uchar[]>
Shinya Kitaoka 120a6e
    if (!sel) throw SMemAllocError("in directionMap");
Shinya Kitaoka 120a6e
    memcpy(sel.get(), m_dir.get(), m_lX * m_lY * sizeof(UCHAR));
Shinya Kitaoka 120a6e
    UCHAR *pSel = sel.get();
Shinya Kitaoka 120a6e
    UCHAR *pDir = m_dir.get();
Shinya Kitaoka 120a6e
    for (int y = 0; y < m_lY; y++)
Shinya Kitaoka 120a6e
      for (int x                    = 0; x < m_lX; x++, pSel++, pDir++)
Shinya Kitaoka 120a6e
        if (*pSel > (UCHAR)0) *pDir = blurRadius(sel.get(), x, y, dBlur);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void CSDirection::setDir01() {
Shinya Kitaoka 120a6e
  int xy      = m_lX * m_lY;
Shinya Kitaoka 120a6e
  UCHAR *pDir = m_dir.get();
Shinya Kitaoka 120a6e
  for (int i = 0; i < xy; i++, pDir++)
Shinya Kitaoka 120a6e
    *pDir = *pDir > (UCHAR)0 ? (UCHAR)1 : (UCHAR)0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void CSDirection::doDir() {
Shinya Kitaoka 120a6e
  if (m_lX > 0 && m_lY > 0 && m_dir) {
Shinya Kitaoka 120a6e
    std::unique_ptr<uchar[]> sel(new UCHAR[m_lX * m_lY]);</uchar[]>
Shinya Kitaoka 120a6e
    if (!sel) throw SMemAllocError("in directionMap");
Shinya Kitaoka 120a6e
    size_t length = (size_t)(m_lX * m_lY * sizeof(UCHAR));
Shinya Kitaoka 120a6e
    memcpy(sel.get(), m_dir.get(), length);
Shinya Kitaoka 120a6e
    makeDir(sel.get());
Shinya Kitaoka 120a6e
    memcpy(sel.get(), m_dir.get(), length);
Shinya Kitaoka 120a6e
    equalizeDir(sel.get(), 3);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void CSDirection::doRadius(const double rH, const double rLR, const double rV,
Shinya Kitaoka 120a6e
                           const double rRL, const int dBlur) {
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    int xy      = m_lX * m_lY;
Shinya Kitaoka 120a6e
    UCHAR *pDir = m_dir.get();
Shinya Kitaoka 120a6e
    double r[4] = {D_CUT_0_1(rH), D_CUT_0_1(rLR), D_CUT_0_1(rV),
Shinya Kitaoka 120a6e
                   D_CUT_0_1(rRL)};
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (int i = 0; i < xy; i++, pDir++)
Shinya Kitaoka 120a6e
      if (*pDir < (UCHAR)50) {
Shinya Kitaoka 120a6e
        *pDir = (UCHAR)0;
Shinya Kitaoka 120a6e
      } else
Shinya Kitaoka 120a6e
        *pDir = getRadius((double)(*pDir - 50), r);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (dBlur > 0) blurRadius(dBlur);
Shinya Kitaoka 120a6e
  } catch (SMemAllocError) {
Shinya Kitaoka 120a6e
    throw;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void CSDirection::getResult(UCHAR *sel) {
Shinya Kitaoka 120a6e
  memcpy(sel, m_dir.get(), (size_t)(m_lX * m_lY * sizeof(UCHAR)));
Toshihiro Shimizu 890ddd
}