/*********************************************************************
 * 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.7 $
 *********************************************************************/

#include "Indexer.h"

namespace prapi
{
	Matrix<int> Indexer::flatten(const Matrix<RGBColor<> >& mat, int levels, int originalLevels)
	{
		int dlevels = levels*levels;

		int rows = mat.getRows(), columns = mat.getColumns();
		Matrix<int> result(rows,columns);

		const RGBColor<>* matData = mat.getData();
		int* resultData = result.getData();

		for (int i=rows*columns;i--; resultData++, matData++)
			*resultData =
				(matData->getRed() * levels / originalLevels) * dlevels +
				(matData->getGreen() * levels / originalLevels) * levels +
				(matData->getBlue() * levels / originalLevels);
		
		return result;
	}

	Matrix<int> Indexer::flatten(const Matrix<RGBColor<> >& mat, Quantizer& r, Quantizer& g, Quantizer& b)
		throw (QuantizationException&)
	{
		int dlevels = g.getLevels()*b.getLevels();
		int levels = b.getLevels();

		int rows = mat.getRows(), columns = mat.getColumns();
		Matrix<int> result(rows,columns);

		const RGBColor<>* matData = mat.getData();
		int* resultData = result.getData();

		for (int i=rows*columns;i--; resultData++, matData++)
			*resultData =
				r.getBinIndex(matData->getRed()) * dlevels +
				g.getBinIndex(matData->getGreen()) * levels +
				b.getBinIndex(matData->getBlue());
		
		return result;
	}

	Matrix<int> Indexer::quantize(const Matrix<double>& mat, Quantizer& q) throw (QuantizationException&)
	{
		Matrix<int> result(mat.getRows(), mat.getColumns());
		const double* data = mat.getData();
		int *resultData = result.getData();
		for (int i=mat.getRows()*mat.getColumns();i--;data++,resultData++)
			*resultData = q.getBinIndex(*data);
		return result;
	}
}
