#ifndef CHROMAPRINT_IMAGE_H_
#define CHROMAPRINT_IMAGE_H_
#include <vector>
#include <algorithm>
#include <cassert>
#ifdef NDEBUG
#define CHROMAPRINT_IMAGE_ROW_TYPE double *
#define CHROMAPRINT_IMAGE_ROW_TYPE_CAST(x, c) x
#else
#define CHROMAPRINT_IMAGE_ROW_TYPE ImageRow
#define CHROMAPRINT_IMAGE_ROW_TYPE_CAST(x, c) ImageRow(x, c)
#endif
namespace chromaprint {
class ImageRow
{
public:
explicit ImageRow(double *data, int columns) : m_data(data), m_columns(columns)
{
}
int NumColumns() const { return m_columns; }
double &Column(int i)
{
assert(0 <= i && i < NumColumns());
return m_data[i];
}
double &operator[](int i)
{
return Column(i);
}
private:
double *m_data;
int m_columns;
};
class Image
{
public:
explicit Image(int columns) : m_columns(columns)
{
}
Image(int columns, int rows) : m_columns(columns), m_data(columns * rows)
{
}
template<class Iterator>
Image(int columns, Iterator first, Iterator last) : m_columns(columns), m_data(first, last)
{
}
int NumColumns() const { return m_columns; }
int NumRows() const { return int(m_data.size() / m_columns); }
void AddRow(const std::vector<double> &row)
{
m_data.resize(m_data.size() + m_columns);
std::copy(row.begin(), row.end(), m_data.end() - m_columns);
}
CHROMAPRINT_IMAGE_ROW_TYPE Row(int i)
{
assert(0 <= i && i < NumRows());
return CHROMAPRINT_IMAGE_ROW_TYPE_CAST(&m_data[m_columns * i], m_columns);
}
CHROMAPRINT_IMAGE_ROW_TYPE operator[](int i)
{
return Row(i);
}
private:
int m_columns;
std::vector<double> m_data;
};
};
#endif