/*********************************************************************
 * This file is part of the PRAPI library.
 *
 * Copyright (C) 2001 Topi Mäenpää and Jaakko Viertola
 * All rights reserved.
 *
 * This program is free software. You can redistribute and/or modify
 * it under the terms of the free software licence found in the
 * accompanying file "COPYING". The licence terms must always be
 * redistributed with this source file. The above copyright notice
 * must be reproduced in all modified and unmodified copies of this
 * source file.
 *
 * $Revision: 1.6 $
 *********************************************************************/

#ifndef _INDEXER_H
#define _INDEXER_H

#include <Matrix.h>
#include "Quantizer.h"
#include "Color.h"

namespace prapi
{
	/**
	 * Indexer produces integer-valued matrices out of multi-channel color
	 * matrices or double-valued matrices.
	 **/
	class Indexer
	{
	public:
		/**
		 * Create an indexed matrix out of a color matrix. Each color
		 * channel is quantized to <i>levels</i> levels. Each channel is
		 * thus given an index in the range [0,levels-1]. The index for a
		 * color is calculated by: R*levels<sup>2</sup> + G*levels + B.
		 * The maximum index will thus be index<sup>3</sup>-1.
		 *
		 * @param mat the matrix to be indexed
		 * @param levels the number of output levels
		 * @param originalLevels the maximum value for a color channel
		 * before flattening
		 **/
		static Matrix<int> flatten(const Matrix<RGBColor<> >& mat, int levels, int originalLevels);

		/**
		 * Create an indexed matrix out of a color matrix. Each color
		 * channel is quantized using a different quantizer. The total
		 * number of levels in the output will equal to r.getLevels() *
		 * g.getLevels() * b.getLevels().
		 *
		 * @param mat the matrix to be indexed
		 * @param r a quantizer for the red color channel		 
		 * @param g a quantizer for the green color channel		 
		 * @param b a quantizer for the blue color channel
		 * @exception QuantizationException& if a quantization error occurs
		 **/
		static Matrix<int> flatten(const Matrix<RGBColor<> >& mat, Quantizer& r, Quantizer& g, Quantizer& b)
			throw (QuantizationException&);

		/**
		 * Generate an integer-valued matrix out of a double-valued matrix.
		 * Each floating-point value is passed to a quantizer and the
		 * returned value is placed in the result matrix.
		 *
		 * @param mat the matrix to be quantized
		 * @param q the quantizer
		 **/
		static Matrix<int> quantize(const Matrix<double>& mat, Quantizer& q) throw (QuantizationException&);
	};
}

#endif
