mirror of https://github.com/KLayout/klayout.git
Added mono image class
This commit is contained in:
parent
2088881110
commit
17cbcc2877
|
|
@ -201,6 +201,8 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the first logical layer for a given layer specification
|
* @brief Returns the first logical layer for a given layer specification
|
||||||
|
* The first value of the pair indicates whether there is a valid mapping.
|
||||||
|
* The second value will give the layer to map to.
|
||||||
*/
|
*/
|
||||||
template <class L>
|
template <class L>
|
||||||
std::pair<bool, unsigned int> first_logical (const L &p) const
|
std::pair<bool, unsigned int> first_logical (const L &p) const
|
||||||
|
|
@ -215,6 +217,8 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the first logical layer for a given layer specification
|
* @brief Returns the first logical layer for a given layer specification
|
||||||
|
* The first value of the pair indicates whether there is a valid mapping.
|
||||||
|
* The second value will give the layer to map to.
|
||||||
*/
|
*/
|
||||||
template <class L>
|
template <class L>
|
||||||
std::pair<bool, unsigned int> first_logical (const L &p, db::Layout &layout) const
|
std::pair<bool, unsigned int> first_logical (const L &p, db::Layout &layout) const
|
||||||
|
|
@ -230,24 +234,21 @@ public:
|
||||||
/**
|
/**
|
||||||
* @brief Query a layer mapping
|
* @brief Query a layer mapping
|
||||||
*
|
*
|
||||||
* @return A pair telling if the layer is mapped (first=true) and
|
* @return A set of layers which are designated targets.
|
||||||
* the logical layer mapped (second) if this is the case.
|
|
||||||
*/
|
*/
|
||||||
std::set<unsigned int> logical (const LDPair &p) const;
|
std::set<unsigned int> logical (const LDPair &p) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Query a layer mapping from a name
|
* @brief Query a layer mapping from a name
|
||||||
*
|
*
|
||||||
* @return A pair telling if the layer is mapped (first=true) and
|
* @return A set of layers which are designated targets.
|
||||||
* the logical layer mapped (second) if this is the case.
|
|
||||||
*/
|
*/
|
||||||
std::set<unsigned int> logical (const std::string &name) const;
|
std::set<unsigned int> logical (const std::string &name) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Query a layer mapping from a name or LDPair
|
* @brief Query a layer mapping from a name or LDPair
|
||||||
*
|
*
|
||||||
* @return A pair telling if the layer is mapped (first=true) and
|
* @return A set of layers which are designated targets.
|
||||||
* the logical layer mapped (second) if this is the case.
|
|
||||||
*
|
*
|
||||||
* @param p The layer that is looked for
|
* @param p The layer that is looked for
|
||||||
*/
|
*/
|
||||||
|
|
@ -256,8 +257,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* @brief Query or install a layer mapping from a name or LDPair
|
* @brief Query or install a layer mapping from a name or LDPair
|
||||||
*
|
*
|
||||||
* @return A pair telling if the layer is mapped (first=true) and
|
* @return A set of layers which are designated targets.
|
||||||
* the logical layer mapped (second) if this is the case.
|
|
||||||
*
|
*
|
||||||
* @param p The layer that is looked for
|
* @param p The layer that is looked for
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,11 @@
|
||||||
namespace lay
|
namespace lay
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// Image implementation
|
||||||
|
|
||||||
Image::Image (unsigned int w, unsigned int h, lay::color_t *data)
|
Image::Image (unsigned int w, unsigned int h, lay::color_t *data)
|
||||||
|
: m_data ()
|
||||||
{
|
{
|
||||||
m_width = w;
|
m_width = w;
|
||||||
m_height = h;
|
m_height = h;
|
||||||
|
|
@ -35,16 +39,21 @@ Image::Image (unsigned int w, unsigned int h, lay::color_t *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
Image::Image (unsigned int w, unsigned int h, const lay::color_t *data, unsigned int stride)
|
Image::Image (unsigned int w, unsigned int h, const lay::color_t *data, unsigned int stride)
|
||||||
|
: m_data ()
|
||||||
{
|
{
|
||||||
m_width = w;
|
m_width = w;
|
||||||
m_height = h;
|
m_height = h;
|
||||||
m_transparent = false;
|
m_transparent = false;
|
||||||
|
|
||||||
lay::color_t *d = new color_t [w * h];
|
tl_assert ((stride % sizeof (lay::color_t)) == 0);
|
||||||
|
stride /= sizeof (lay::color_t);
|
||||||
|
|
||||||
|
lay::color_t *d = new lay::color_t [w * h];
|
||||||
|
lay::color_t *new_data = d;
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
for (unsigned int i = 0; i < h; ++i) {
|
for (unsigned int i = 0; i < h; ++i) {
|
||||||
for (unsigned int i = 0; i < h; ++i) {
|
for (unsigned int j = 0; j < w; ++j) {
|
||||||
*d++ = *data++;
|
*d++ = *data++;
|
||||||
}
|
}
|
||||||
if (stride > w) {
|
if (stride > w) {
|
||||||
|
|
@ -53,7 +62,7 @@ Image::Image (unsigned int w, unsigned int h, const lay::color_t *data, unsigned
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_data.reset (new ImageData (d, w * h));
|
m_data.reset (new ImageData (new_data, w * h));
|
||||||
}
|
}
|
||||||
|
|
||||||
Image::Image ()
|
Image::Image ()
|
||||||
|
|
@ -211,4 +220,150 @@ Image::diff (const Image &other) const
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// MonoImage implementation
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
stride_from_width (unsigned int w)
|
||||||
|
{
|
||||||
|
// Qt needs 32bit-aligned data
|
||||||
|
return 4 * ((w + 31) / 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
MonoImage::MonoImage (unsigned int w, unsigned int h, uint8_t *data)
|
||||||
|
{
|
||||||
|
m_width = w;
|
||||||
|
m_height = h;
|
||||||
|
m_stride = stride_from_width (w);
|
||||||
|
m_data.reset (new MonoImageData (data, m_stride * h));
|
||||||
|
}
|
||||||
|
|
||||||
|
MonoImage::MonoImage (unsigned int w, unsigned int h, const uint8_t *data, unsigned int stride)
|
||||||
|
{
|
||||||
|
m_width = w;
|
||||||
|
m_height = h;
|
||||||
|
m_stride = stride_from_width (w);
|
||||||
|
|
||||||
|
uint8_t *d = new uint8_t [m_stride * h];
|
||||||
|
uint8_t *new_data = d;
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
for (unsigned int i = 0; i < h; ++i) {
|
||||||
|
memcpy (d, data, m_stride);
|
||||||
|
d += m_stride;
|
||||||
|
data += m_stride;
|
||||||
|
if (stride > m_stride) {
|
||||||
|
data += stride - m_stride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_data.reset (new MonoImageData (new_data, m_stride * h));
|
||||||
|
}
|
||||||
|
|
||||||
|
MonoImage::MonoImage ()
|
||||||
|
{
|
||||||
|
m_width = 0;
|
||||||
|
m_height = 0;
|
||||||
|
m_stride = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MonoImage::MonoImage (const MonoImage &other)
|
||||||
|
{
|
||||||
|
operator= (other);
|
||||||
|
}
|
||||||
|
|
||||||
|
MonoImage::MonoImage (MonoImage &&other)
|
||||||
|
{
|
||||||
|
swap (other);
|
||||||
|
}
|
||||||
|
|
||||||
|
MonoImage::~MonoImage ()
|
||||||
|
{
|
||||||
|
// .. nothing yet ..
|
||||||
|
}
|
||||||
|
|
||||||
|
MonoImage &
|
||||||
|
MonoImage::operator= (const MonoImage &other)
|
||||||
|
{
|
||||||
|
if (this != &other) {
|
||||||
|
m_width = other.m_width;
|
||||||
|
m_height = other.m_height;
|
||||||
|
m_stride = other.m_stride;
|
||||||
|
m_data = other.m_data;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
MonoImage &
|
||||||
|
MonoImage::operator= (MonoImage &&other)
|
||||||
|
{
|
||||||
|
if (this != &other) {
|
||||||
|
swap (other);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MonoImage::swap (MonoImage &other)
|
||||||
|
{
|
||||||
|
if (this == &other) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::swap (m_width, other.m_width);
|
||||||
|
std::swap (m_height, other.m_height);
|
||||||
|
std::swap (m_stride, other.m_stride);
|
||||||
|
m_data.swap (other.m_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MonoImage::fill (bool value)
|
||||||
|
{
|
||||||
|
uint8_t c = value ? 0xff : 0;
|
||||||
|
uint8_t *d = data ();
|
||||||
|
for (unsigned int i = 0; i < m_height; ++i) {
|
||||||
|
for (unsigned int j = 0; j < m_stride; ++j) {
|
||||||
|
*d++ = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *
|
||||||
|
MonoImage::scan_line (unsigned int n)
|
||||||
|
{
|
||||||
|
tl_assert (n < m_height);
|
||||||
|
return m_data->data () + n * m_stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t *
|
||||||
|
MonoImage::scan_line (unsigned int n) const
|
||||||
|
{
|
||||||
|
tl_assert (n < m_height);
|
||||||
|
return m_data->data () + n * m_stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *
|
||||||
|
MonoImage::data ()
|
||||||
|
{
|
||||||
|
return m_data->data ();
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t *
|
||||||
|
MonoImage::data () const
|
||||||
|
{
|
||||||
|
return m_data->data ();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_QT)
|
||||||
|
QImage
|
||||||
|
MonoImage::to_image () const
|
||||||
|
{
|
||||||
|
QImage img = QImage ((const uchar *) data (), m_width, m_height, QImage::Format_MonoLSB);
|
||||||
|
img.setColor (0, 0xff000000);
|
||||||
|
img.setColor (1, 0xffffffff);
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
#include "tlCopyOnWrite.h"
|
#include "tlCopyOnWrite.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
#if defined(HAVE_QT)
|
#if defined(HAVE_QT)
|
||||||
# include <QImage>
|
# include <QImage>
|
||||||
|
|
@ -38,7 +39,7 @@ namespace lay
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief An 32bit RGBA image class
|
* @brief An 32bit RGB/RGBA image class
|
||||||
*
|
*
|
||||||
* This class substitutes QImage in Qt-less applications.
|
* This class substitutes QImage in Qt-less applications.
|
||||||
* It provides 32bit RGBA pixels with the format used by lay::Color.
|
* It provides 32bit RGBA pixels with the format used by lay::Color.
|
||||||
|
|
@ -131,6 +132,14 @@ public:
|
||||||
return m_height;
|
return m_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the image stride (number of bytes per row)
|
||||||
|
*/
|
||||||
|
unsigned int stride () const
|
||||||
|
{
|
||||||
|
return sizeof (lay::color_t) * m_width;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Fills the image with the given color
|
* @brief Fills the image with the given color
|
||||||
*/
|
*/
|
||||||
|
|
@ -228,6 +237,171 @@ private:
|
||||||
tl::copy_on_write_ptr<ImageData> m_data;
|
tl::copy_on_write_ptr<ImageData> m_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief An monochrome image class
|
||||||
|
*
|
||||||
|
* This class substitutes QImage for monochrome images in Qt-less applications.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class LAYBASIC_PUBLIC MonoImage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Creates an image with the given height and width
|
||||||
|
*
|
||||||
|
* If data is given, the image is initialized with the given data and will take ownership over the
|
||||||
|
* data block.
|
||||||
|
*
|
||||||
|
* Lines are byte-aligned.
|
||||||
|
*/
|
||||||
|
MonoImage (unsigned int w, unsigned int h, uint8_t *data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Creates an image with the given height and width
|
||||||
|
*
|
||||||
|
* If data is given, the image is initialized with the given data. A copy of the data is created.
|
||||||
|
*
|
||||||
|
* "stride" specifies the stride (distance in bytes between two rows of data).
|
||||||
|
* The size of the data block needs to be stride*h elements or bytes(w)*h if stride is not given.
|
||||||
|
*/
|
||||||
|
MonoImage (unsigned int w, unsigned int h, const uint8_t *data = 0, unsigned int stride = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Default constructor
|
||||||
|
*/
|
||||||
|
MonoImage ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Copy constructor
|
||||||
|
*/
|
||||||
|
MonoImage (const MonoImage &other);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Move constructor
|
||||||
|
*/
|
||||||
|
MonoImage (MonoImage &&other);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destructor
|
||||||
|
*/
|
||||||
|
~MonoImage ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Assignment
|
||||||
|
*/
|
||||||
|
MonoImage &operator= (const MonoImage &other);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Move constructor
|
||||||
|
*/
|
||||||
|
MonoImage &operator= (MonoImage &&other);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Swaps this image with another one
|
||||||
|
*/
|
||||||
|
void swap (MonoImage &other);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the images width
|
||||||
|
*/
|
||||||
|
unsigned int width () const
|
||||||
|
{
|
||||||
|
return m_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the images width
|
||||||
|
*/
|
||||||
|
unsigned int height () const
|
||||||
|
{
|
||||||
|
return m_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the image stride (number of bytes per row)
|
||||||
|
*/
|
||||||
|
unsigned int stride () const
|
||||||
|
{
|
||||||
|
return m_stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Fills the image with the given color
|
||||||
|
*/
|
||||||
|
void fill (bool value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the scanline for row n
|
||||||
|
*/
|
||||||
|
uint8_t *scan_line (unsigned int n);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the scanline for row n (const version)
|
||||||
|
*/
|
||||||
|
const uint8_t *scan_line (unsigned int n) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the data pointer
|
||||||
|
*/
|
||||||
|
uint8_t *data ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the data pointer (const version)
|
||||||
|
*/
|
||||||
|
const uint8_t *data () const;
|
||||||
|
|
||||||
|
#if defined(HAVE_QT)
|
||||||
|
/**
|
||||||
|
* @brief Produces a QMonoImage object from the image
|
||||||
|
*/
|
||||||
|
QImage to_image () const;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
class MonoImageData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MonoImageData ()
|
||||||
|
: mp_data (0), m_length (0)
|
||||||
|
{
|
||||||
|
// .. nothing yet ..
|
||||||
|
}
|
||||||
|
|
||||||
|
MonoImageData (uint8_t *data, size_t length)
|
||||||
|
: mp_data (data), m_length (length)
|
||||||
|
{
|
||||||
|
// .. nothing yet ..
|
||||||
|
}
|
||||||
|
|
||||||
|
MonoImageData (const MonoImageData &other)
|
||||||
|
{
|
||||||
|
m_length = other.length ();
|
||||||
|
mp_data = new uint8_t [other.length ()];
|
||||||
|
memcpy (mp_data, other.data (), m_length * sizeof (uint8_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
~MonoImageData ()
|
||||||
|
{
|
||||||
|
delete[] mp_data;
|
||||||
|
mp_data = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t length () const { return m_length; }
|
||||||
|
uint8_t *data () { return mp_data; }
|
||||||
|
const uint8_t *data () const { return mp_data; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t *mp_data;
|
||||||
|
size_t m_length;
|
||||||
|
|
||||||
|
MonoImageData &operator= (const MonoImageData &other);
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned int m_width, m_height;
|
||||||
|
unsigned int m_stride;
|
||||||
|
tl::copy_on_write_ptr<MonoImageData> m_data;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -36,8 +36,8 @@ static bool compare_images (const QImage &qimg, const std::string &au)
|
||||||
qimg2.load (tl::to_qstring (au));
|
qimg2.load (tl::to_qstring (au));
|
||||||
|
|
||||||
if (qimg2.width () == (int) qimg.width () && qimg2.height () == (int) qimg.height ()) {
|
if (qimg2.width () == (int) qimg.width () && qimg2.height () == (int) qimg.height ()) {
|
||||||
for (int i = 0; i < qimg.width (); ++i) {
|
for (int j = 0; j < qimg.height (); ++j) {
|
||||||
for (int j = 0; j < qimg.height (); ++j) {
|
for (int i = 0; i < qimg.width (); ++i) {
|
||||||
if (((const lay::color_t *) qimg.scanLine (j))[i] != ((const lay::color_t *) qimg2.scanLine (j))[i]) {
|
if (((const lay::color_t *) qimg.scanLine (j))[i] != ((const lay::color_t *) qimg2.scanLine (j))[i]) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -49,6 +49,58 @@ static bool compare_images (const QImage &qimg, const std::string &au)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool compare_images_mono (const QImage &qimg, const std::string &au)
|
||||||
|
{
|
||||||
|
QImage qimg2;
|
||||||
|
qimg2.load (tl::to_qstring (au));
|
||||||
|
|
||||||
|
if (qimg2.width () == (int) qimg.width () && qimg2.height () == (int) qimg.height ()) {
|
||||||
|
// NOTE: slooooow ...
|
||||||
|
for (int j = 0; j < qimg.height (); ++j) {
|
||||||
|
for (int i = 0; i < qimg.width (); ++i) {
|
||||||
|
if ((qimg.scanLine (j)[i / 8] & (0x80 >> (i % 8))) != (qimg2.scanLine (j)[i / 8] & (0x80 >> (i % 8)))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool compare_images (const lay::Image &img, const lay::Image &img2)
|
||||||
|
{
|
||||||
|
if (img2.width () == img.width () && img2.height () == img.height ()) {
|
||||||
|
for (unsigned int j = 0; j < img.height (); ++j) {
|
||||||
|
for (unsigned int i = 0; i < img.width (); ++i) {
|
||||||
|
if (((const lay::color_t *) img.scan_line (j))[i] != ((const lay::color_t *) img2.scan_line (j))[i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool compare_images (const lay::MonoImage &img, const lay::MonoImage &img2)
|
||||||
|
{
|
||||||
|
if (img2.width () == img.width () && img2.height () == img.height ()) {
|
||||||
|
for (unsigned int j = 0; j < img.height (); ++j) {
|
||||||
|
for (unsigned int i = 0; i < img.stride (); ++i) {
|
||||||
|
if (((const uint8_t *) img.scan_line (j))[i] != ((const uint8_t *) img2.scan_line (j))[i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TEST(1)
|
TEST(1)
|
||||||
|
|
@ -56,6 +108,7 @@ TEST(1)
|
||||||
lay::Image img (15, 25);
|
lay::Image img (15, 25);
|
||||||
EXPECT_EQ (img.width (), 15);
|
EXPECT_EQ (img.width (), 15);
|
||||||
EXPECT_EQ (img.height (), 25);
|
EXPECT_EQ (img.height (), 25);
|
||||||
|
EXPECT_EQ (img.stride (), 15 * sizeof (lay::color_t));
|
||||||
|
|
||||||
EXPECT_EQ (img.transparent (), false);
|
EXPECT_EQ (img.transparent (), false);
|
||||||
img.set_transparent (true);
|
img.set_transparent (true);
|
||||||
|
|
@ -85,6 +138,7 @@ TEST(1)
|
||||||
EXPECT_EQ (img.scan_line (5)[10], 0x332211);
|
EXPECT_EQ (img.scan_line (5)[10], 0x332211);
|
||||||
|
|
||||||
img2 = img;
|
img2 = img;
|
||||||
|
EXPECT_EQ (compare_images (img, img2), true);
|
||||||
EXPECT_EQ (img.scan_line (5)[10], 0x332211);
|
EXPECT_EQ (img.scan_line (5)[10], 0x332211);
|
||||||
EXPECT_EQ (img2.scan_line (5)[10], 0x332211);
|
EXPECT_EQ (img2.scan_line (5)[10], 0x332211);
|
||||||
|
|
||||||
|
|
@ -94,21 +148,25 @@ TEST(1)
|
||||||
EXPECT_EQ (img2.width (), 10);
|
EXPECT_EQ (img2.width (), 10);
|
||||||
EXPECT_EQ (img2.height (), 16);
|
EXPECT_EQ (img2.height (), 16);
|
||||||
img2.fill (0x010203);
|
img2.fill (0x010203);
|
||||||
|
EXPECT_EQ (compare_images (img, img2), false);
|
||||||
|
|
||||||
EXPECT_EQ (img.scan_line (5)[10], 0x332211);
|
EXPECT_EQ (img.scan_line (5)[10], 0x332211);
|
||||||
EXPECT_EQ (img2.scan_line (5)[8], 0x010203);
|
EXPECT_EQ (img2.scan_line (5)[8], 0x010203);
|
||||||
|
|
||||||
img = std::move (img2);
|
img = std::move (img2);
|
||||||
|
EXPECT_EQ (compare_images (img, img2), false);
|
||||||
EXPECT_EQ (img.width (), 10);
|
EXPECT_EQ (img.width (), 10);
|
||||||
EXPECT_EQ (img.height (), 16);
|
EXPECT_EQ (img.height (), 16);
|
||||||
EXPECT_EQ (img.scan_line (5)[8], 0x010203);
|
EXPECT_EQ (img.scan_line (5)[8], 0x010203);
|
||||||
|
|
||||||
lay::Image img3 (img);
|
lay::Image img3 (img);
|
||||||
|
EXPECT_EQ (compare_images (img, img3), true);
|
||||||
EXPECT_EQ (img3.width (), 10);
|
EXPECT_EQ (img3.width (), 10);
|
||||||
EXPECT_EQ (img3.height (), 16);
|
EXPECT_EQ (img3.height (), 16);
|
||||||
EXPECT_EQ (img3.scan_line (5)[8], 0x010203);
|
EXPECT_EQ (img3.scan_line (5)[8], 0x010203);
|
||||||
|
|
||||||
img.fill (0x102030);
|
img.fill (0x102030);
|
||||||
|
EXPECT_EQ (compare_images (img, img3), false);
|
||||||
EXPECT_EQ (img3.width (), 10);
|
EXPECT_EQ (img3.width (), 10);
|
||||||
EXPECT_EQ (img3.height (), 16);
|
EXPECT_EQ (img3.height (), 16);
|
||||||
EXPECT_EQ (img3.scan_line (5)[8], 0x010203);
|
EXPECT_EQ (img3.scan_line (5)[8], 0x010203);
|
||||||
|
|
@ -120,6 +178,14 @@ TEST(1)
|
||||||
EXPECT_EQ (img4.width (), 10);
|
EXPECT_EQ (img4.width (), 10);
|
||||||
EXPECT_EQ (img4.height (), 16);
|
EXPECT_EQ (img4.height (), 16);
|
||||||
EXPECT_EQ (img4.scan_line (5)[8], 0x102030);
|
EXPECT_EQ (img4.scan_line (5)[8], 0x102030);
|
||||||
|
|
||||||
|
// other constructors
|
||||||
|
EXPECT_EQ (compare_images (lay::Image (img4.width (), img4.height (), (const lay::color_t *) img4.data ()), img4), true);
|
||||||
|
EXPECT_EQ (compare_images (lay::Image (img4.width (), img4.height (), (const lay::color_t *) img4.data (), img4.stride ()), img4), true);
|
||||||
|
|
||||||
|
lay::color_t *dnew = new lay::color_t [ img4.width () * img4.height () * sizeof (lay::color_t) ];
|
||||||
|
memcpy (dnew, (const lay::color_t *) img4.data (), img4.width () * img4.height () * sizeof (lay::color_t));
|
||||||
|
EXPECT_EQ (compare_images (lay::Image (img4.width (), img4.height (), dnew), img4), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HAVE_QT)
|
#if defined(HAVE_QT)
|
||||||
|
|
@ -260,3 +326,108 @@ TEST(3)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Monochrome version
|
||||||
|
|
||||||
|
TEST(11)
|
||||||
|
{
|
||||||
|
lay::MonoImage img (15, 25);
|
||||||
|
EXPECT_EQ (img.width (), 15);
|
||||||
|
EXPECT_EQ (img.height (), 25);
|
||||||
|
EXPECT_EQ (img.stride (), 4);
|
||||||
|
|
||||||
|
img.fill (true);
|
||||||
|
EXPECT_EQ (img.scan_line (5)[1], 0xff);
|
||||||
|
|
||||||
|
lay::MonoImage img2;
|
||||||
|
img2 = img;
|
||||||
|
EXPECT_EQ (img2.width (), 15);
|
||||||
|
EXPECT_EQ (img2.height (), 25);
|
||||||
|
|
||||||
|
EXPECT_EQ (img.scan_line (5)[1], 0xff);
|
||||||
|
EXPECT_EQ (img2.scan_line (5)[1], 0xff);
|
||||||
|
|
||||||
|
img2.fill (false);
|
||||||
|
EXPECT_EQ (img.scan_line (5)[1], 0xff);
|
||||||
|
EXPECT_EQ (img2.scan_line (5)[1], 0);
|
||||||
|
|
||||||
|
img2.swap (img);
|
||||||
|
EXPECT_EQ (img2.scan_line (5)[1], 0xff);
|
||||||
|
EXPECT_EQ (img.scan_line (5)[1], 0);
|
||||||
|
|
||||||
|
img2 = img;
|
||||||
|
EXPECT_EQ (compare_images (img, img2), true);
|
||||||
|
EXPECT_EQ (img.scan_line (5)[1], 0);
|
||||||
|
EXPECT_EQ (img2.scan_line (5)[1], 0);
|
||||||
|
|
||||||
|
img2 = lay::MonoImage (10, 16);
|
||||||
|
EXPECT_EQ (img.width (), 15);
|
||||||
|
EXPECT_EQ (img.height (), 25);
|
||||||
|
EXPECT_EQ (img2.width (), 10);
|
||||||
|
EXPECT_EQ (img2.height (), 16);
|
||||||
|
img2.fill (true);
|
||||||
|
EXPECT_EQ (compare_images (img, img2), false);
|
||||||
|
|
||||||
|
EXPECT_EQ (img.scan_line (5)[1], 0);
|
||||||
|
EXPECT_EQ (img2.scan_line (5)[0], 0xff);
|
||||||
|
|
||||||
|
img = std::move (img2);
|
||||||
|
EXPECT_EQ (compare_images (img, img2), false);
|
||||||
|
EXPECT_EQ (img.width (), 10);
|
||||||
|
EXPECT_EQ (img.height (), 16);
|
||||||
|
EXPECT_EQ (img.scan_line (5)[0], 0xff);
|
||||||
|
|
||||||
|
lay::MonoImage img3 (img);
|
||||||
|
EXPECT_EQ (compare_images (img, img3), true);
|
||||||
|
EXPECT_EQ (img3.width (), 10);
|
||||||
|
EXPECT_EQ (img3.height (), 16);
|
||||||
|
EXPECT_EQ (img3.scan_line (5)[1], 0xff);
|
||||||
|
|
||||||
|
img.fill (false);
|
||||||
|
EXPECT_EQ (compare_images (img, img3), false);
|
||||||
|
EXPECT_EQ (img3.width (), 10);
|
||||||
|
EXPECT_EQ (img3.height (), 16);
|
||||||
|
EXPECT_EQ (img3.scan_line (5)[1], 0xff);
|
||||||
|
EXPECT_EQ (img.width (), 10);
|
||||||
|
EXPECT_EQ (img.height (), 16);
|
||||||
|
EXPECT_EQ (img.scan_line (5)[1], 0);
|
||||||
|
|
||||||
|
lay::MonoImage img4 (std::move (img));
|
||||||
|
EXPECT_EQ (img4.width (), 10);
|
||||||
|
EXPECT_EQ (img4.height (), 16);
|
||||||
|
EXPECT_EQ (img4.scan_line (5)[1], 0);
|
||||||
|
|
||||||
|
// other constructors
|
||||||
|
EXPECT_EQ (compare_images (lay::MonoImage (img4.width (), img4.height (), (const uint8_t *) img4.data ()), img4), true);
|
||||||
|
EXPECT_EQ (compare_images (lay::MonoImage (img4.width (), img4.height (), (const uint8_t *) img4.data (), img4.stride ()), img4), true);
|
||||||
|
|
||||||
|
uint8_t *dnew = new uint8_t [ img4.width () * img4.height () * sizeof (uint8_t) ];
|
||||||
|
memcpy (dnew, (const uint8_t *) img4.data (), img4.stride () * img4.height ());
|
||||||
|
EXPECT_EQ (compare_images (lay::MonoImage (img4.width (), img4.height (), dnew), img4), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_QT)
|
||||||
|
|
||||||
|
TEST(12)
|
||||||
|
{
|
||||||
|
lay::MonoImage img (227, 231);
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < img.stride (); ++i) {
|
||||||
|
for (unsigned int j = 0; j < img.height (); ++j) {
|
||||||
|
img.scan_line (j) [i] = uint8_t (i * j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPECT_EQ (img.to_image ().format () == QImage::Format_MonoLSB, true);
|
||||||
|
|
||||||
|
std::string tmp = tmp_file ("test.png");
|
||||||
|
QImage qimg = img.to_image ();
|
||||||
|
qimg.save (tl::to_qstring (tmp));
|
||||||
|
tl::info << "PNG file written to " << tmp;
|
||||||
|
|
||||||
|
std::string au = tl::testsrc () + "/testdata/lay/au_mono.png";
|
||||||
|
tl::info << "PNG file read from " << au;
|
||||||
|
|
||||||
|
EXPECT_EQ (compare_images_mono (qimg.convertToFormat (QImage::Format_Mono), au), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -153,7 +153,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
tl::MutexLocker locker (&ms_lock);
|
tl::MutexLocker locker (&ms_lock);
|
||||||
std::swap (mp_x, other.mp_x);
|
|
||||||
std::swap (mp_holder, other.mp_holder);
|
std::swap (mp_holder, other.mp_holder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -250,7 +249,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
X *mp_x;
|
|
||||||
copy_on_write_holder<X> *mp_holder;
|
copy_on_write_holder<X> *mp_holder;
|
||||||
|
|
||||||
void release ()
|
void release ()
|
||||||
|
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 6.4 KiB |
Loading…
Reference in New Issue