qcross/libqnono/nonogramnumbers.cpp

166 lines
5.0 KiB
C++

/***************************************************************************
* Copyright (C) 2012 Stefan Bühler <stbuehler@web.de> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "nonogramnumbers.h"
#include "nonogramimage.h"
#include <QDataStream>
namespace libqnono {
static const quint64 NonogramNumbers_MAGIC = Q_UINT64_C(0x0c395a301353aad2);
NonogramNumbers::NonogramNumbers() {
}
NonogramNumbers::NonogramNumbers(const vv_num & rows, const vv_num & columns)
: m_rows(rows), m_columns(columns) {
}
NonogramNumbers::NonogramNumbers(const NonogramImage & image) {
calcFromImage(image);
}
NonogramNumbers::NonogramNumbers(const QImage & image) {
NonogramImage img(image);
calcFromImage(img);
}
void NonogramNumbers::calcFromImage(const NonogramImage & image) {
int rows = image.height(), cols = image.width();
m_rows.clear(); m_rows.resize(rows);
m_columns.clear(); m_columns.resize(cols);
for (int row = 0; row < rows; ++row) {
quint16 *val = 0;
for (int col = 0; col < cols; ++col) {
bool b = image.pixel(col, row);
if (!val && b) {
m_rows[row].append(1);
val = &m_rows[row].last();
} else if (b) {
++(*val);
} else {
val = 0;
}
}
if (m_rows[row].isEmpty()) m_rows[row].append(0);
}
for (int col = 0; col < cols; ++col) {
quint16 *val = 0;
for (int row = 0; row < rows; ++row) {
bool b = image.pixel(col, row);
if (!val && b) {
m_columns[col].append(1);
val = &m_columns[col].last();
} else if (b) {
++(*val);
} else {
val = 0;
}
}
if (m_columns[col].isEmpty()) m_columns[col].append(0);
}
}
void NonogramNumbers::updateFromImage(const NonogramImage & image, int x, int y) {
int rows = image.height(), cols = image.width();
m_rows[y].clear();
m_columns[x].clear();
{
int row = y;
quint16 *val = 0;
for (int col = 0; col < cols; ++col) {
bool b = image.pixel(col, row);
if (!val && b) {
m_rows[row].append(1);
val = &m_rows[row].last();
} else if (b) {
++(*val);
} else {
val = 0;
}
}
if (m_rows[row].isEmpty()) m_rows[row].append(0);
}
{
int col = x;
quint16 *val = 0;
for (int row = 0; row < rows; ++row) {
bool b = image.pixel(col, row);
if (!val && b) {
m_columns[col].append(1);
val = &m_columns[col].last();
} else if (b) {
++(*val);
} else {
val = 0;
}
}
if (m_columns[col].isEmpty()) m_columns[col].append(0);
}
}
bool NonogramNumbers::readFromStream(QDataStream & stream) {
quint64 magic;
stream >> magic;
if (NonogramNumbers_MAGIC != magic || QDataStream::Ok != stream.status()) {
if (QDataStream::ReadPastEnd != stream.status()) stream.setStatus(QDataStream::ReadCorruptData);
return false;
}
vv_num rows, columns;
stream >> rows >> columns;
if (QDataStream::Ok != stream.status()) return false;
m_rows = rows; m_columns = columns;
return true;
}
void NonogramNumbers::writeToStream(QDataStream & stream) {
stream << NonogramNumbers_MAGIC << m_rows << m_columns;
}
bool NonogramNumbers::operator==(const NonogramNumbers &other) const {
return m_rows == other.m_rows && m_columns == other.m_columns;
}
int NonogramNumbers::maximumNumberCount() const {
int r = 1;
foreach (const v_num &line, m_rows) r = qMax<int>(r, line.count());
foreach (const v_num &line, m_columns) r = qMax<int>(r, line.count());
return r;
}
bool NonogramNumbers::check(const NonogramImage & image) const {
if (size() != image.size()) return FALSE;
NonogramNumbers tmp(image);
return *this == tmp;
}
QDataStream & operator<<(QDataStream & stream, NonogramNumbers & numbers) {
numbers.writeToStream(stream);
return stream;
}
QDataStream & operator>>(QDataStream & stream, NonogramNumbers & numbers) {
numbers.readFromStream(stream);
return stream;
}
}