Toshihiro Shimizu 890ddd
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
/*!
Toshihiro Shimizu 890ddd
  The RunsMapP is an auxiliary raster greymap type used to store run-length 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.
Toshihiro Shimizu 890ddd
  This means that users must always iterate from the beginning of a line to get valid
Toshihiro Shimizu 890ddd
  data.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  The following coding is adopted to extract the run length from the run headers:
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \li We'll use the last 2 bits only in the headers. With these, we can cover directly
Toshihiro Shimizu 890ddd
      those runs up to 4 pixels length.
Toshihiro Shimizu 890ddd
  \li When the length >=4, we require that one byte is taken in the run to store the length
Toshihiro Shimizu 890ddd
      up to 256 pixels.
Toshihiro Shimizu 890ddd
  \li When the length >= 256, we take 4 additional bytes to store the length (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
*/
Toshihiro Shimizu 890ddd
class RunsMap : public TRasterT<tpixelgr8></tpixelgr8>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	RunsMap(int lx, int ly) : TRasterT<tpixelgr8>(lx, ly) { clear(); }</tpixelgr8>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	const UCHAR &runHeader(int x, int y) const { return pixels(y)[x].value; }
Toshihiro Shimizu 890ddd
	UCHAR &runHeader(int x, int y) { return pixels(y)[x].value; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TUINT32 runLength(const TPixelGR8 *run, bool reversed = false) const;
Toshihiro Shimizu 890ddd
	TUINT32 runLength(int x, int y, bool reversed = false) const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return runLength(pixels(y) + x, reversed);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	void setRunLength(TPixelGR8 *run, TUINT32 length);
Toshihiro Shimizu 890ddd
	void setRunLength(int x, int y, TUINT32 length) { setRunLength(pixels(y) + x, length); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef WIN32
Toshihiro Shimizu 890ddd
template class DV_EXPORT_API TSmartPointerT<runsmap>;</runsmap>
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class RunsMapP : public TSmartPointerT<runsmap></runsmap>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	RunsMapP() {}
Toshihiro Shimizu 890ddd
	RunsMapP(int lx, int ly) : TSmartPointerT<runsmap>(new RunsMap(lx, ly)) {}</runsmap>
Toshihiro Shimizu 890ddd
	RunsMapP(const TDimension &d) : 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>
Toshihiro Shimizu 890ddd
void buildRunsMap(RunsMapP &runsMap, const TRasterPT<pixel> &ras, const PixelSelector &selector)</pixel>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//Traverse the raster, extracting run lengths
Toshihiro Shimizu 890ddd
	int y, ly = ras->getLy();
Toshihiro Shimizu 890ddd
	for (y = 0; y < ly; ++y) {
Toshihiro Shimizu 890ddd
		Pixel *lineStart = (Pixel *)ras->pixels(y), *lineEnd = lineStart + ras->getLx();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		Pixel *pix, *runStart;
Toshihiro Shimizu 890ddd
		typename PixelSelector::value_type colorIndex;
Toshihiro Shimizu 890ddd
		for (pix = runStart = lineStart, colorIndex = selector.value(*pix);
Toshihiro Shimizu 890ddd
			 pix < lineEnd; ++pix)
Toshihiro Shimizu 890ddd
			if (selector.value(*pix) != colorIndex) {
Toshihiro Shimizu 890ddd
				runsMap->setRunLength(runStart - lineStart, y, pix - runStart);
Toshihiro Shimizu 890ddd
				runStart = pix;
Toshihiro Shimizu 890ddd
				colorIndex = selector.value(*pix);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		runsMap->setRunLength(runStart - lineStart, y, pix - runStart);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif //RUNSMAP_H