Shinya Kitaoka 810553
#pragma once
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef RUNSMAP_H
Toshihiro Shimizu 890ddd
#define RUNSMAP_H
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "traster.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//*********************************************************************************************************
Toshihiro Shimizu 890ddd
//    Run Maps
Toshihiro Shimizu 890ddd
//*********************************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Shinya Kitaoka 120a6e
  The RunsMapP is an auxiliary raster greymap type used to store run-length
Shinya Kitaoka 120a6e
  informations
Toshihiro Shimizu 890ddd
  about an image.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  Not every image pixel has valid informations. Only pixels corresponding to
Toshihiro Shimizu 890ddd
  run headers do, and those include the position of the next run header.
Shinya Kitaoka 120a6e
  This means that users must always iterate from the beginning of a line to get
Shinya Kitaoka 120a6e
  valid
Toshihiro Shimizu 890ddd
  data.
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  The following coding is adopted to extract the run length from the run
Shinya Kitaoka 120a6e
  headers:
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  \li We'll use the last 2 bits only in the headers. With these, we can cover
Shinya Kitaoka 120a6e
  directly
Toshihiro Shimizu 890ddd
      those runs up to 4 pixels length.
Shinya Kitaoka 120a6e
  \li When the length >=4, we require that one byte is taken in the run to store
Shinya Kitaoka 120a6e
  the length
Toshihiro Shimizu 890ddd
      up to 256 pixels.
Shinya Kitaoka 120a6e
  \li When the length >= 256, we take 4 additional bytes to store the length
Shinya Kitaoka 120a6e
  (which this time
Toshihiro Shimizu 890ddd
      could go up to billions).
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  Observe that the runsmap supports a symmetrical representation, useful
Toshihiro Shimizu 890ddd
  to traverse runs both forward and backwards. This means that 2 headers are
Toshihiro Shimizu 890ddd
  provided for each run, at the opposite ends (unless the run is 1 pixel-width).
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka d1f6c4
class RunsMap final : public TRasterT<tpixelgr8> {</tpixelgr8>
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  RunsMap(int lx, int ly) : TRasterT<tpixelgr8>(lx, ly) { clear(); }</tpixelgr8>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  const UCHAR &runHeader(int x, int y) const { return pixels(y)[x].value; }
Shinya Kitaoka 120a6e
  UCHAR &runHeader(int x, int y) { return pixels(y)[x].value; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TUINT32 runLength(const TPixelGR8 *run, bool reversed = false) const;
Shinya Kitaoka 120a6e
  TUINT32 runLength(int x, int y, bool reversed = false) const {
Shinya Kitaoka 120a6e
    return runLength(pixels(y) + x, reversed);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  void setRunLength(TPixelGR8 *run, TUINT32 length);
Shinya Kitaoka 120a6e
  void setRunLength(int x, int y, TUINT32 length) {
Shinya Kitaoka 120a6e
    setRunLength(pixels(y) + x, length);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
template class DV_EXPORT_API TSmartPointerT<runsmap>;</runsmap>
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class RunsMapP final : public TSmartPointerT<runsmap> {</runsmap>
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  RunsMapP() {}
Shinya Kitaoka 120a6e
  RunsMapP(int lx, int ly) : TSmartPointerT<runsmap>(new RunsMap(lx, ly)) {}</runsmap>
Shinya Kitaoka 120a6e
  RunsMapP(const TDimension &d)
Shinya Kitaoka 120a6e
      : TSmartPointerT<runsmap>(new RunsMap(d.lx, d.ly)) {}</runsmap>
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename pixel,="" pixelselector="" typename=""></typename>
Shinya Kitaoka 120a6e
void buildRunsMap(RunsMapP &runsMap, const TRasterPT<pixel> &ras,</pixel>
Shinya Kitaoka 120a6e
                  const PixelSelector &selector) {
Shinya Kitaoka 120a6e
  // Traverse the raster, extracting run lengths
Shinya Kitaoka 120a6e
  int y, ly = ras->getLy();
Shinya Kitaoka 120a6e
  for (y = 0; y < ly; ++y) {
Shinya Kitaoka 120a6e
    Pixel *lineStart = (Pixel *)ras->pixels(y),
Shinya Kitaoka 120a6e
          *lineEnd   = lineStart + ras->getLx();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    Pixel *pix, *runStart;
Shinya Kitaoka 120a6e
    typename PixelSelector::value_type colorIndex;
Shinya Kitaoka 120a6e
    for (pix = runStart = lineStart, colorIndex = selector.value(*pix);
Shinya Kitaoka 120a6e
         pix < lineEnd; ++pix)
Shinya Kitaoka 120a6e
      if (selector.value(*pix) != colorIndex) {
Shinya Kitaoka 120a6e
        runsMap->setRunLength(runStart - lineStart, y, pix - runStart);
Shinya Kitaoka 120a6e
        runStart   = pix;
Shinya Kitaoka 120a6e
        colorIndex = selector.value(*pix);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    runsMap->setRunLength(runStart - lineStart, y, pix - runStart);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#endif  // RUNSMAP_H