166 lines
5.0 KiB
C++
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;
|
||
|
}
|
||
|
}
|