Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tropcm.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tpalette.h"
Toshihiro Shimizu 890ddd
#include "trop_borders.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "pixelselectors.h"
Toshihiro Shimizu 890ddd
#include "runsmap.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define INCLUDE_HPP
Toshihiro Shimizu 890ddd
#include "raster_edge_iterator.h"
Toshihiro Shimizu 890ddd
#include "borders_extractor.h"
Toshihiro Shimizu 890ddd
#define INCLUDE_HPP
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// tcg includes
Toshihiro Shimizu 890ddd
#include "tcg/deleter_types.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// STL includes
Toshihiro Shimizu 890ddd
#include <deque></deque>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*============================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
    Explanation
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  Despeckling is a noise-removal procedure which aims at eliminating small blots
Shinya Kitaoka 120a6e
of color
Toshihiro Shimizu 890ddd
  from an image.
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  We will assume that speckles are recognized with uniform color (which means -
Shinya Kitaoka 120a6e
image
Toshihiro Shimizu 890ddd
  discretization should be externally performed).
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  We will currently assume that the despeckling procedure works only on the ink
Shinya Kitaoka 120a6e
or paint plane of a
Toshihiro Shimizu 890ddd
  TRasterCM32 instance, not both (should be extended in the future).
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  The image is traversed to isolate regions with the same color and, if their
Shinya Kitaoka 120a6e
area is
Toshihiro Shimizu 890ddd
  below the specified threshold, they get removed or changed of color.
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  Color change looks at the area's neighbouring pixels for the most used color
Shinya Kitaoka 120a6e
to use for
Shinya Kitaoka 120a6e
  replacement. If NO neighbouring color can be found, the area is made
Shinya Kitaoka 120a6e
transparent.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
==============================================================================================*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
using namespace TRop::borders;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//************************************************************************
Toshihiro Shimizu 890ddd
//    Pixel Selectors
Toshihiro Shimizu 890ddd
//************************************************************************
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class InkSelectorCM32 {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  typedef TPixelCM32 pixel_type;
Shinya Kitaoka 120a6e
  typedef TUINT32 value_type;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  InkSelectorCM32() {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  value_type transparent() const { return 0; }
Shinya Kitaoka 120a6e
  bool transparent(const pixel_type &pix) const { return value(pix) == 0; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  value_type value(const pixel_type &pix) const { return pix.getInk(); }
Shinya Kitaoka 120a6e
  bool equal(const pixel_type &a, const pixel_type &b) const {
Shinya Kitaoka 120a6e
    return value(a) == value(b);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bool skip(const value_type &prevLeftValue,
Shinya Kitaoka 120a6e
            const value_type &leftValue) const {
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename channel="" pixel,="" typename=""></typename>
Shinya Kitaoka 120a6e
class InkSelectorRGBM {
Shinya Kitaoka 120a6e
  bool m_transparentIsWhite;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  typedef PIXEL pixel_type;
Shinya Kitaoka 120a6e
  typedef CHANNEL value_type;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  InkSelectorRGBM(bool transparentIsWhite)
Shinya Kitaoka 120a6e
      : m_transparentIsWhite(transparentIsWhite) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  value_type transparent() const { return 0; }
Shinya Kitaoka 120a6e
  bool transparent(const pixel_type &pix) const { return value(pix) == 0; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  value_type value(const pixel_type &pix) const {
Shinya Kitaoka 120a6e
    if (m_transparentIsWhite)
Shinya Kitaoka 120a6e
      return (pix == PIXEL::White) ? 0 : 1;
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      return (pix.m == 0) ? 0 : 1;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  bool equal(const pixel_type &a, const pixel_type &b) const {
Shinya Kitaoka 120a6e
    return value(a) == value(b);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool skip(const value_type &prevLeftValue,
Shinya Kitaoka 120a6e
            const value_type &leftValue) const {
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename channel="" pixel,="" typename=""></typename>
Shinya Kitaoka 120a6e
class InkSelectorGR {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  typedef PIXEL pixel_type;
Shinya Kitaoka 120a6e
  typedef CHANNEL value_type;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  InkSelectorGR() {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  value_type transparent() const { return PIXEL::maxChannelValue; }
Shinya Kitaoka 120a6e
  bool transparent(const pixel_type &pix) const { return value(pix) == 0; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  value_type value(const pixel_type &pix) const {
Shinya Kitaoka 120a6e
    return (pix.value == PIXEL::maxChannelValue) ? 0 : 1;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  bool equal(const pixel_type &a, const pixel_type &b) const {
Shinya Kitaoka 120a6e
    return value(a) == value(b);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool skip(const value_type &prevLeftValue,
Shinya Kitaoka 120a6e
            const value_type &leftValue) const {
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//************************************************************************
Toshihiro Shimizu 890ddd
//    Border class
Toshihiro Shimizu 890ddd
//************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct Border {
Shinya Kitaoka 120a6e
  std::vector<tpoint> m_points;</tpoint>
Shinya Kitaoka 120a6e
  int m_x0, m_y0, m_x1, m_y1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  Border()
Shinya Kitaoka 120a6e
      : m_x0((std::numeric_limits<int>::max)())</int>
Shinya Kitaoka 120a6e
      , m_y0(m_x0)
Shinya Kitaoka 120a6e
      , m_x1(-m_x0)
Shinya Kitaoka 120a6e
      , m_y1(m_x1) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void addPoint(const TPoint &p) {
Shinya Kitaoka 120a6e
    // Update the region box
Shinya Kitaoka 120a6e
    if (p.x < m_x0) m_x0 = p.x;
Shinya Kitaoka 120a6e
    if (p.x > m_x1) m_x1 = p.x;
Shinya Kitaoka 120a6e
    if (p.y < m_y0) m_y0 = p.y;
Shinya Kitaoka 120a6e
    if (p.y > m_y1) m_y1 = p.y;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Add the vertex
Shinya Kitaoka 120a6e
    m_points.push_back(p);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void clear() {
Shinya Kitaoka 120a6e
    m_points.clear();
Shinya Kitaoka 120a6e
    m_x0 = (std::numeric_limits<int>::max)(), m_y0 = m_x0, m_x1 = -m_x0,</int>
Shinya Kitaoka 120a6e
    m_y1 = m_x1;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//************************************************************************
Toshihiro Shimizu 890ddd
//    Base classes
Toshihiro Shimizu 890ddd
//************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//========================================================================
Toshihiro Shimizu 890ddd
//    Borders Painter
Toshihiro Shimizu 890ddd
//========================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename pix=""></typename>
Shinya Kitaoka 120a6e
class BordersPainter {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  typedef Pix pixel_type;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
protected:
Shinya Kitaoka 120a6e
  TRasterPT<pixel_type> m_ras;</pixel_type>
Shinya Kitaoka 120a6e
  RunsMapP m_runsMap;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  BordersPainter(const TRasterPT<pixel_type> &ras) : m_ras(ras) {}</pixel_type>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  const TRasterPT<pixel_type> &ras() { return m_ras; }</pixel_type>
Shinya Kitaoka 120a6e
  RunsMapP &runsMap() { return m_runsMap; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void paintLine(int x, int y0, int y1) const;
Shinya Kitaoka 120a6e
  void paintBorder(const Border &border) const;
Shinya Kitaoka 120a6e
  void paintBorders(const std::deque<border *=""> &borders) const {</border>
Shinya Kitaoka 120a6e
    size_t i, size = borders.size();
Shinya Kitaoka 120a6e
    for (i = 0; i < size; ++i) paintBorder(*borders[i]);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
protected:
Shinya Kitaoka 120a6e
  virtual void paintPixel(pixel_type *pix) const = 0;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename pix=""></typename>
Shinya Kitaoka 120a6e
void BordersPainter<pix>::paintBorder(const Border &border) const {</pix>
Shinya Kitaoka 120a6e
  const std::vector<tpoint> &points = border.m_points;</tpoint>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  size_t i, size_1 = points.size() - 1;
Shinya Kitaoka 120a6e
  for (i = 0; i < size_1; ++i) {
Shinya Kitaoka 120a6e
    const TPoint &p = points[i];
Shinya Kitaoka 120a6e
    paintLine(p.x, p.y, points[i + 1].y);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  paintLine(points[size_1].x, points[size_1].y, points[0].y);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename pix=""></typename>
Shinya Kitaoka 120a6e
void BordersPainter<pix>::paintLine(int x, int y0, int y1) const {</pix>
Shinya Kitaoka 120a6e
  for (int j = y0; j < y1; ++j) {
Shinya Kitaoka 120a6e
    TPixelGR8 *runPix = m_runsMap->pixels(j) + x;
Shinya Kitaoka 120a6e
    int l, runLength = 0, hierarchy = 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    do {
Shinya Kitaoka 120a6e
      if (runPix->value & TRop::borders::_HIERARCHY_INCREASE) ++hierarchy;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      // Update vars
Shinya Kitaoka 120a6e
      runLength += l = m_runsMap->runLength(runPix);
Shinya Kitaoka 120a6e
      runPix += l;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      if ((runPix - 1)->value & TRop::borders::_HIERARCHY_DECREASE) --hierarchy;
Shinya Kitaoka 120a6e
    } while (hierarchy > 0);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    pixel_type *pix = m_ras->pixels(j) + x, *pixEnd = pix + runLength;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    for (; pix < pixEnd; ++pix) paintPixel(pix);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//========================================================================
Toshihiro Shimizu 890ddd
//    Despeckling Reader
Toshihiro Shimizu 890ddd
//========================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class DespecklingReader {
Toshihiro Shimizu 890ddd
protected:
Shinya Kitaoka 120a6e
  std::deque<border *=""> m_borders;</border>
Shinya Kitaoka 120a6e
  Border m_border;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int m_sizeTol;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  DespecklingReader(int sizeTol) : m_sizeTol(sizeTol) {}
Shinya Kitaoka 120a6e
  ~DespecklingReader();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int sizeTol() const { return m_sizeTol; }
Shinya Kitaoka 120a6e
  bool isSpeckle(const Border &border) {
Shinya Kitaoka 120a6e
    return border.m_x1 - border.m_x0 <= m_sizeTol &&
Shinya Kitaoka 120a6e
           border.m_y1 - border.m_y0 <= m_sizeTol;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void openContainer(const TPoint &pos);
Shinya Kitaoka 120a6e
  void addElement(const TPoint &pos);
Shinya Kitaoka 120a6e
  virtual void closeContainer();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  const std::deque<border *=""> &borders() const { return m_borders; }</border>
Shinya Kitaoka 120a6e
  std::deque<border *=""> &borders() { return m_borders; }</border>
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
DespecklingReader::~DespecklingReader() {
Shinya Kitaoka 120a6e
  std::for_each(m_borders.begin(), m_borders.end(), tcg::deleter<border>());</border>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void DespecklingReader::openContainer(const TPoint &pos) {
Shinya Kitaoka 120a6e
  m_border.clear();
Shinya Kitaoka 120a6e
  m_border.addPoint(pos);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void DespecklingReader::addElement(const TPoint &pos) {
Shinya Kitaoka 120a6e
  m_border.addPoint(pos);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void DespecklingReader::closeContainer() {
Shinya Kitaoka 120a6e
  if (isSpeckle(m_border)) m_borders.push_back(new Border(m_border));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//************************************************************************
Toshihiro Shimizu 890ddd
//    Specialized classes
Toshihiro Shimizu 890ddd
//************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//========================================================================
Toshihiro Shimizu 890ddd
//    Replace Painters
Toshihiro Shimizu 890ddd
//========================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename pix=""></typename>
Shinya Kitaoka 120a6e
class ReplacePainter : public BordersPainter<pix> {</pix>
Shinya Kitaoka 120a6e
  typename ReplacePainter::pixel_type m_color;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  ReplacePainter(const TRasterPT<typename replacepainter::pixel_type=""> &ras)</typename>
Shinya Kitaoka 120a6e
      : BordersPainter<pix>(ras) {}</pix>
Shinya Kitaoka 120a6e
  ReplacePainter(const TRasterPT<typename replacepainter::pixel_type=""> &ras,</typename>
Shinya Kitaoka 120a6e
                 const typename ReplacePainter::pixel_type &color)
Shinya Kitaoka 120a6e
      : BordersPainter<pix>(ras), m_color(color) {}</pix>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  const typename ReplacePainter::pixel_type &color() const { return m_color; }
Shinya Kitaoka 120a6e
  typename ReplacePainter::pixel_type &color() { return m_color; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void paintPixel(typename ReplacePainter::pixel_type *pix) const override {
Shinya Kitaoka 120a6e
    *pix = m_color;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <>
Shinya Kitaoka 120a6e
class ReplacePainter<tpixelcm32> : public BordersPainter<tpixelcm32> {</tpixelcm32></tpixelcm32>
Shinya Kitaoka 120a6e
  TUINT32 m_value;
Shinya Kitaoka 120a6e
  TUINT32 m_keepMask;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  ReplacePainter(const TRasterPT<pixel_type> &ras)</pixel_type>
Shinya Kitaoka 120a6e
      : BordersPainter<tpixelcm32>(ras), m_value(0), m_keepMask(0) {}</tpixelcm32>
Shinya Kitaoka 120a6e
  ReplacePainter(const TRasterPT<pixel_type> &ras, TUINT32 value,</pixel_type>
Shinya Kitaoka 120a6e
                 TUINT32 keepMask)
Shinya Kitaoka 120a6e
      : BordersPainter<tpixelcm32>(ras), m_value(value), m_keepMask(keepMask) {}</tpixelcm32>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  const TUINT32 &value() const { return m_value; }
Shinya Kitaoka 120a6e
  TUINT32 &value() { return m_value; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  const TUINT32 &keepMask() const { return m_keepMask; }
Shinya Kitaoka 120a6e
  TUINT32 &keepMask() { return m_keepMask; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  void paintPixel(pixel_type *pix) const override {
Shinya Kitaoka 120a6e
    *pix = TPixelCM32(m_value | (pix->getValue() & m_keepMask));
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//========================================================================
Toshihiro Shimizu 890ddd
//    Isolated Despeckling
Toshihiro Shimizu 890ddd
//========================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename pixelselector=""></typename>
Shinya Kitaoka 120a6e
class IsolatedReader : public DespecklingReader {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  typedef typename PixelSelector::pixel_type pixel_type;
Shinya Kitaoka 120a6e
  typedef typename PixelSelector::value_type value_type;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  const PixelSelector &m_selector;
Shinya Kitaoka 120a6e
  bool m_ok;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  IsolatedReader(const PixelSelector &selector, int sizeTol);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void openContainer(const RasterEdgeIterator<pixelselector> &it);</pixelselector>
Shinya Kitaoka 120a6e
  void addElement(const RasterEdgeIterator<pixelselector> &it);</pixelselector>
Shinya Kitaoka 473e70
  void closeContainer() override;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename pixelselector=""></typename>
Shinya Kitaoka 120a6e
IsolatedReader<pixelselector>::IsolatedReader(const PixelSelector &selector,</pixelselector>
Shinya Kitaoka 120a6e
                                              int sizeTol)
Shinya Kitaoka 120a6e
    : DespecklingReader(sizeTol), m_selector(selector) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename pixelselector=""></typename>
Shinya Kitaoka 120a6e
void IsolatedReader<pixelselector>::openContainer(</pixelselector>
Shinya Kitaoka 120a6e
    const RasterEdgeIterator<pixelselector> &it) {</pixelselector>
Shinya Kitaoka 120a6e
  m_ok = (it.leftColor() == m_selector.transparent());
Shinya Kitaoka 120a6e
  if (!m_ok) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  DespecklingReader::openContainer(it.pos());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename pixelselector=""></typename>
Shinya Kitaoka 120a6e
void IsolatedReader<pixelselector>::addElement(</pixelselector>
Shinya Kitaoka 120a6e
    const RasterEdgeIterator<pixelselector> &it) {</pixelselector>
Shinya Kitaoka 120a6e
  if (!m_ok) return;
Shinya Kitaoka 120a6e
  m_ok = (it.leftColor() == m_selector.transparent());
Shinya Kitaoka 120a6e
  if (!m_ok) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  DespecklingReader::addElement(it.pos());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename pixelselector=""></typename>
Shinya Kitaoka 120a6e
void IsolatedReader<pixelselector>::closeContainer() {</pixelselector>
Shinya Kitaoka 120a6e
  if (m_ok) DespecklingReader::closeContainer();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//*********************************************************************************************************
Toshihiro Shimizu 890ddd
//    Despeckling Mains
Toshihiro Shimizu 890ddd
//*********************************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Shinya Kitaoka 120a6e
  Applies despeckling (paint or removal of small blots of uniform color) to the
Shinya Kitaoka 120a6e
  image.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename channel="" pixel,="" typename=""></typename>
Shinya Kitaoka 120a6e
void doDespeckleRGBM(const TRasterPT<pixel> &ras, int sizeThreshold,</pixel>
Shinya Kitaoka 120a6e
                     bool transparentIsWhite) {
Shinya Kitaoka 120a6e
  InkSelectorRGBM<pixel, channel=""> selector(transparentIsWhite);</pixel,>
Shinya Kitaoka 120a6e
  IsolatedReader<inkselectorrgbm<pixel, channel="">> reader(selector,</inkselectorrgbm<pixel,>
Shinya Kitaoka 120a6e
                                                         sizeThreshold);
Shinya Kitaoka 120a6e
  ReplacePainter<pixel> painter(</pixel>
Shinya Kitaoka 120a6e
      ras, transparentIsWhite ? PIXEL::White : PIXEL::Transparent);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRop::borders::readBorders(ras, selector, reader, &painter.runsMap());
Shinya Kitaoka 120a6e
  painter.paintBorders(reader.borders());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename channel="" pixel,="" typename=""></typename>
Shinya Kitaoka 120a6e
void doDespeckleGR(const TRasterPT<pixel> &ras, int sizeThreshold) {</pixel>
Shinya Kitaoka 120a6e
  InkSelectorGR<pixel, channel=""> selector;</pixel,>
Shinya Kitaoka 120a6e
  IsolatedReader<inkselectorgr<pixel, channel="">> reader(selector, sizeThreshold);</inkselectorgr<pixel,>
Shinya Kitaoka 120a6e
  ReplacePainter<pixel> painter(ras, PIXEL::maxChannelValue);</pixel>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRop::borders::readBorders(ras, selector, reader, &painter.runsMap());
Shinya Kitaoka 120a6e
  painter.paintBorders(reader.borders());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void doDespeckleCM32(const TRasterPT<tpixelcm32> &ras, int sizeThreshold,</tpixelcm32>
Shinya Kitaoka 120a6e
                     bool check) {
Shinya Kitaoka 120a6e
  TRasterCM32P rasCM(ras);
Shinya Kitaoka 120a6e
  rasCM->lock();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  InkSelectorCM32 selector;
Shinya Kitaoka 120a6e
  IsolatedReader<inkselectorcm32> reader(selector, sizeThreshold);</inkselectorcm32>
Shinya Kitaoka 120a6e
  ReplacePainter<tpixelcm32> painter(</tpixelcm32>
Shinya Kitaoka 120a6e
      rasCM, check ? 0xffffff00 : 0x000000ff,
Shinya Kitaoka 120a6e
      0);  // 0xffffff00 is a special non-mapped full ink pixel
Shinya Kitaoka 120a6e
           // 0x000000ff is a full transparent paint pixel
Shinya Kitaoka 120a6e
  TRop::borders::readBorders(rasCM, selector, reader, &painter.runsMap());
Shinya Kitaoka 120a6e
  painter.paintBorders(reader.borders());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  rasCM->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRop::despeckle(const TRasterP &ras, int sizeThreshold, bool check,
Shinya Kitaoka 120a6e
                     bool transparentIsWhite) {
Shinya Kitaoka 120a6e
  ras->lock();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (TRasterCM32P(ras)) {
Shinya Kitaoka 120a6e
    doDespeckleCM32(ras, sizeThreshold, check);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (TRaster32P(ras)) {
Shinya Kitaoka 120a6e
    doDespeckleRGBM<tpixel32, uchar="">(ras, sizeThreshold, transparentIsWhite);</tpixel32,>
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (TRaster64P(ras)) {
Shinya Kitaoka 120a6e
    doDespeckleRGBM<tpixel64, ushort="">(ras, sizeThreshold, transparentIsWhite);</tpixel64,>
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (TRasterGR8P(ras)) {
Shinya Kitaoka 120a6e
    doDespeckleGR<tpixelgr8, uchar="">(ras, sizeThreshold);</tpixelgr8,>
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (TRasterGR16P(ras)) {
Shinya Kitaoka 120a6e
    doDespeckleGR<tpixelgr16, ushort="">(ras, sizeThreshold);</tpixelgr16,>
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ras->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  Performs a copy of rin and then applies despeckling.
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
void TRop::despeckle(const TRasterP &rout, const TRasterP &rin,
Shinya Kitaoka 120a6e
                     int sizeThreshold, bool check) {
Shinya Kitaoka 120a6e
  TRop::copy(rout, rin);
Shinya Kitaoka 120a6e
  TRop::despeckle(rout, sizeThreshold, check);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//*********************************************************************************************************
Toshihiro Shimizu 890ddd
//    Majority Despeckling
Toshihiro Shimizu 890ddd
//*********************************************************************************************************
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename pixelselector=""></typename>
Shinya Kitaoka 120a6e
class FillingReader : public DespecklingReader {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  typedef typename PixelSelector::pixel_type pixel_type;
Shinya Kitaoka 120a6e
  typedef typename PixelSelector::value_type value_type;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  ReplacePainter<tpixelgr8> m_painter;</tpixelgr8>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  FillingReader(const TRasterGR8P &rasGR, int sizeTol)
Shinya Kitaoka 120a6e
      : DespecklingReader(sizeTol), m_painter(rasGR, TPixelGR8::Black) {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void openContainer(const RasterEdgeIterator<pixelselector> &it);</pixelselector>
Shinya Kitaoka 120a6e
  void addElement(const RasterEdgeIterator<pixelselector> &it);</pixelselector>
Shinya Kitaoka 473e70
  void closeContainer() override;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  RunsMapP &runsMap() { return m_painter.runsMap(); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename pixelselector=""></typename>
Shinya Kitaoka 120a6e
void FillingReader<pixelselector>::openContainer(</pixelselector>
Shinya Kitaoka 120a6e
    const RasterEdgeIterator<pixelselector> &it) {</pixelselector>
Shinya Kitaoka 120a6e
  DespecklingReader::openContainer(it.pos());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename pixelselector=""></typename>
Shinya Kitaoka 120a6e
void FillingReader<pixelselector>::addElement(</pixelselector>
Shinya Kitaoka 120a6e
    const RasterEdgeIterator<pixelselector> &it) {</pixelselector>
Shinya Kitaoka 120a6e
  DespecklingReader::addElement(it.pos());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename pixelselector=""></typename>
Shinya Kitaoka 120a6e
void FillingReader<pixelselector>::closeContainer() {</pixelselector>
Shinya Kitaoka 120a6e
  if (isSpeckle(m_border)) m_painter.paintBorder(m_border);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  DespecklingReader::closeContainer();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline TPoint direction(const TPoint &a, const TPoint &b) {
Shinya Kitaoka 120a6e
  return TPoint((b.x > a.x) ? 1 : (b.x < a.x) ? -1 : 0,
Shinya Kitaoka 120a6e
                (b.y > a.y) ? 1 : (b.y < a.y) ? -1 : 0);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename pixel,="" pixelselector="" typename=""></typename>
Toshihiro Shimizu 890ddd
bool majority(const TRasterPT<pixel> ras, const TRasterGR8P &rasGR,</pixel>
Shinya Kitaoka 120a6e
              const PixelSelector &selector, const Border &border,
Shinya Kitaoka 120a6e
              typename PixelSelector::value_type &color) {
Shinya Kitaoka 120a6e
  typedef typename PixelSelector::value_type value_type;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Build a histogram of all found colors around the border
Shinya Kitaoka 120a6e
  std::map<value_type, int=""> histogram;</value_type,>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  Pixel *pix, *basePix = ras->pixels(0);
Shinya Kitaoka 120a6e
  TPixelGR8 *grPix;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int diff, x, y, lx = ras->getLx(), ly = ras->getLy(), wrap = ras->getWrap();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  assert(border.m_points[1].y > border.m_points[0].y);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Iterate the raster along the border
Shinya Kitaoka 120a6e
  const std::vector<tpoint> &points = border.m_points;</tpoint>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  RasterEdgeIterator<pixelselector> start(ras, selector, points[0],</pixelselector>
Shinya Kitaoka 120a6e
                                          direction(points[0], points[1])),
Shinya Kitaoka 120a6e
      it(start);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  size_t next = 1, size = points.size();
Shinya Kitaoka 120a6e
  do {
Shinya Kitaoka 120a6e
    while (it.pos() != points[next]) {
Shinya Kitaoka 120a6e
      pix  = it.leftPix();
Shinya Kitaoka 120a6e
      diff = pix - basePix;
Shinya Kitaoka 120a6e
      x    = diff % wrap;
Shinya Kitaoka 120a6e
      y    = diff / wrap;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      if (x >= 0 && y >= 0 && x < lx && y < ly) {
Shinya Kitaoka 120a6e
        grPix = rasGR->pixels(y) + x;
Shinya Kitaoka 120a6e
        if (grPix->value) ++histogram[it.leftColor()];
Shinya Kitaoka 120a6e
      }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      it.setEdge(it.pos() + it.dir(), it.dir());
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    next = (next + 1) % size;
Shinya Kitaoka 120a6e
    it.setEdge(it.pos(), direction(it.pos(), points[next]));
Shinya Kitaoka 120a6e
  } while (it != start);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!histogram.empty()) {
Shinya Kitaoka 120a6e
    // Return the most found color
Shinya Kitaoka 120a6e
    color = histogram.begin()->first;
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename pix=""></typename>
Shinya Kitaoka 120a6e
void majorityDespeckle(const TRasterPT<pix> &ras, int sizeThreshold) {</pix>
Shinya Kitaoka 120a6e
  typedef typename TRop::borders::PixelSelector<pix> pixel_selector;</pix>
Shinya Kitaoka 120a6e
  typedef typename pixel_selector::pixel_type pixel_type;
Shinya Kitaoka 120a6e
  typedef typename pixel_selector::value_type value_type;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ras->lock();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Use a temporary bitmap (well, a bytemap - for now?) to store the found
Shinya Kitaoka 120a6e
  // speckles
Shinya Kitaoka 120a6e
  TRasterGR8P rasGR(ras->getSize());
Shinya Kitaoka 120a6e
  rasGR->fill(TPixelGR8::White);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Find the speckles and draw them on the bitmap
Shinya Kitaoka 120a6e
  pixel_selector selector;
Shinya Kitaoka 120a6e
  FillingReader<pixel_selector> reader(rasGR, sizeThreshold);</pixel_selector>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRop::borders::readBorders(ras, selector, reader, &reader.runsMap());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Now, operate each speckle. Try to apply a majority color to the speckle
Shinya Kitaoka 120a6e
  ReplacePainter<pixel_type> painter(ras);</pixel_type>
Shinya Kitaoka 120a6e
  painter.runsMap() = reader.runsMap();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ReplacePainter<tpixelgr8> painterGR(rasGR, TPixelGR8::White);</tpixelgr8>
Shinya Kitaoka 120a6e
  painterGR.runsMap() = reader.runsMap();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::deque<border *=""> borders =</border>
Shinya Kitaoka 120a6e
      reader.borders();  // Note that the DEEP copy is NEEDED
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int processedCount = 1;
Shinya Kitaoka 120a6e
  while (processedCount > 0 && !borders.empty()) {
Shinya Kitaoka 120a6e
    processedCount = 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    // Traverse the speckles list. Try to apply majority.
Shinya Kitaoka 120a6e
    Border *current, *last = borders.back();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    do {
Shinya Kitaoka 120a6e
      current = borders.front();
Shinya Kitaoka 120a6e
      borders.pop_front();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      value_type color;
Shinya Kitaoka 120a6e
      if (majority(ras, rasGR, selector, *current, color)) {
Shinya Kitaoka 120a6e
        ++processedCount;
Shinya Kitaoka 120a6e
        painter.color() = color;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
        painter.paintBorder(*current);
Shinya Kitaoka 120a6e
        painterGR.paintBorder(*current);
Shinya Kitaoka 120a6e
      } else
Shinya Kitaoka 120a6e
        borders.push_back(current);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    } while (current != last);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Speckles may remain. In this case, fill with transparent.
Shinya Kitaoka 120a6e
  painter.color() = selector.transparent();
Shinya Kitaoka 120a6e
  while (!borders.empty()) {
Shinya Kitaoka 120a6e
    Border *current = borders.front();
Shinya Kitaoka 120a6e
    painter.paintBorder(*current);
Shinya Kitaoka 120a6e
    borders.pop_front();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ras->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRop::majorityDespeckle(const TRasterP &ras, int sizeThreshold) {
Shinya Kitaoka 120a6e
  TRaster32P ras32(ras);
Shinya Kitaoka 120a6e
  if (ras32) {
Shinya Kitaoka 120a6e
    ::majorityDespeckle(ras32, sizeThreshold);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRaster64P ras64(ras);
Shinya Kitaoka 120a6e
  if (ras64) {
Shinya Kitaoka 120a6e
    ::majorityDespeckle(ras64, sizeThreshold);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRasterGR8P rasGR8(ras);
Shinya Kitaoka 120a6e
  if (rasGR8) {
Shinya Kitaoka 120a6e
    ::majorityDespeckle(rasGR8, sizeThreshold);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRasterGR16P rasGR16(ras);
Shinya Kitaoka 120a6e
  if (rasGR16) {
Shinya Kitaoka 120a6e
    ::majorityDespeckle(rasGR16, sizeThreshold);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRasterCM32P rasCM32(ras);
Shinya Kitaoka 120a6e
  if (rasCM32) {
Shinya Kitaoka 120a6e
    // Not yet implemented
Shinya Kitaoka 120a6e
    assert(false);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    //::majorityDespeckleCM(rasCM32, sizeThreshold, toneTol);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}