mirror of https://github.com/KLayout/klayout.git
Equality operator in PixelBuffer
This commit is contained in:
parent
958e1f7c59
commit
101544ab78
|
|
@ -143,6 +143,12 @@ Class<lay::PixelBuffer> decl_PixelBuffer ("lay", "PixelBuffer",
|
|||
"\n"
|
||||
"The pixels are basically uninitialized. You will need to use \\fill to initialize them to a certain value."
|
||||
) +
|
||||
gsi::method ("==", &lay::PixelBuffer::operator==, gsi::arg ("other"),
|
||||
"@brief Returns a value indicating whether self is identical to the other image\n"
|
||||
) +
|
||||
gsi::method ("!=", &lay::PixelBuffer::operator!=, gsi::arg ("other"),
|
||||
"@brief Returns a value indicating whether self is not identical to the other image\n"
|
||||
) +
|
||||
gsi::method ("transparent=", &lay::PixelBuffer::set_transparent, gsi::arg ("t"),
|
||||
"@brief Sets a flag indicating whether the pixel buffer supports an alpha channel\n"
|
||||
"\n"
|
||||
|
|
@ -224,7 +230,9 @@ Class<lay::PixelBuffer> decl_PixelBuffer ("lay", "PixelBuffer",
|
|||
"transparency through an optional alpha channel. The color format for a pixel is "
|
||||
"\"0xAARRGGBB\" where 'AA' is the alpha value which is ignored in non-transparent mode.\n"
|
||||
"\n"
|
||||
"This class supports basic operations such as initialization, single-pixel access and I/O to PNG."
|
||||
"This class supports basic operations such as initialization, single-pixel access and I/O to PNG.\n"
|
||||
"\n"
|
||||
"This class has been introduced in version 0.28."
|
||||
);
|
||||
|
||||
|
||||
|
|
@ -335,6 +343,12 @@ Class<lay::BitmapBuffer> decl_BitmapBuffer ("lay", "BitmapBuffer",
|
|||
"\n"
|
||||
"The pixels are basically uninitialized. You will need to use \\fill to initialize them to a certain value."
|
||||
) +
|
||||
gsi::method ("==", &lay::BitmapBuffer::operator==, gsi::arg ("other"),
|
||||
"@brief Returns a value indicating whether self is identical to the other image\n"
|
||||
) +
|
||||
gsi::method ("!=", &lay::BitmapBuffer::operator!=, gsi::arg ("other"),
|
||||
"@brief Returns a value indicating whether self is not identical to the other image\n"
|
||||
) +
|
||||
gsi::method ("fill", &lay::BitmapBuffer::fill, gsi::arg ("color"),
|
||||
"@brief Fills the pixel buffer with the given pixel value\n"
|
||||
) +
|
||||
|
|
@ -391,7 +405,9 @@ Class<lay::BitmapBuffer> decl_BitmapBuffer ("lay", "BitmapBuffer",
|
|||
"This object is mainly provided for offline rendering of layouts in Qt-less environments.\n"
|
||||
"It supports a rectangular pixel space with color values encoded in single bits.\n"
|
||||
"\n"
|
||||
"This class supports basic operations such as initialization, single-pixel access and I/O to PNG."
|
||||
"This class supports basic operations such as initialization, single-pixel access and I/O to PNG.\n"
|
||||
"\n"
|
||||
"This class has been introduced in version 0.28."
|
||||
);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -169,6 +169,31 @@ PixelBuffer::~PixelBuffer ()
|
|||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
bool
|
||||
PixelBuffer::operator== (const PixelBuffer &other) const
|
||||
{
|
||||
if (width () != other.width () || height () != other.height ()) {
|
||||
return false;
|
||||
}
|
||||
if (transparent () != other.transparent ()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
lay::color_t m = transparent () ? 0xffffffff : 0xffffff;
|
||||
for (unsigned int i = 0; i < other.height (); ++i) {
|
||||
const lay::color_t *d = scan_line (i);
|
||||
const lay::color_t *de = d + width ();
|
||||
const lay::color_t *dd = other.scan_line (i);
|
||||
while (d != de) {
|
||||
if (((*d++ ^ *dd++) & m) != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
PixelBuffer &
|
||||
PixelBuffer::operator= (const PixelBuffer &other)
|
||||
{
|
||||
|
|
@ -485,6 +510,34 @@ BitmapBuffer::~BitmapBuffer ()
|
|||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
bool
|
||||
BitmapBuffer::operator== (const BitmapBuffer &other) const
|
||||
{
|
||||
if (width () != other.width () || height () != other.height ()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < other.height (); ++i) {
|
||||
const uint8_t *d = scan_line (i);
|
||||
const uint8_t *dd = other.scan_line (i);
|
||||
unsigned int bits_left = width ();
|
||||
while (bits_left >= 8) {
|
||||
if (*d++ != *dd++) {
|
||||
return false;
|
||||
}
|
||||
bits_left -= 8;
|
||||
}
|
||||
if (bits_left > 0) {
|
||||
unsigned int m = (0x01 << bits_left) - 1;
|
||||
if (((*d ^ *dd) & m) != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
BitmapBuffer &
|
||||
BitmapBuffer::operator= (const BitmapBuffer &other)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -111,6 +111,19 @@ public:
|
|||
*/
|
||||
~PixelBuffer ();
|
||||
|
||||
/**
|
||||
* @brief Equality
|
||||
*/
|
||||
bool operator== (const PixelBuffer &other) const;
|
||||
|
||||
/**
|
||||
* @brief Inequality
|
||||
*/
|
||||
bool operator!= (const PixelBuffer &other) const
|
||||
{
|
||||
return !operator== (other);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Assignment
|
||||
*/
|
||||
|
|
@ -334,6 +347,19 @@ public:
|
|||
*/
|
||||
BitmapBuffer (BitmapBuffer &&other);
|
||||
|
||||
/**
|
||||
* @brief Equality
|
||||
*/
|
||||
bool operator== (const BitmapBuffer &other) const;
|
||||
|
||||
/**
|
||||
* @brief Inequality
|
||||
*/
|
||||
bool operator!= (const BitmapBuffer &other) const
|
||||
{
|
||||
return !operator== (other);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -74,35 +74,12 @@ static bool compare_images_mono (const QImage &qimg, const std::string &au)
|
|||
|
||||
static bool compare_images (const lay::PixelBuffer &img, const lay::PixelBuffer &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;
|
||||
}
|
||||
return img == img2;
|
||||
}
|
||||
|
||||
static bool compare_images (const lay::BitmapBuffer &img, const lay::BitmapBuffer &img2)
|
||||
{
|
||||
if (img2.width () == img.width () && img2.height () == img.height ()) {
|
||||
// NOTE: slooooow ...
|
||||
for (unsigned int j = 0; j < img.height (); ++j) {
|
||||
for (unsigned int i = 0; i < img.width (); ++i) {
|
||||
if ((img.scan_line (j)[i / 8] & (0x01 << (i % 8))) != (img2.scan_line (j)[i / 8] & (0x01 << (i % 8)))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return img == img2;
|
||||
}
|
||||
|
||||
TEST(1)
|
||||
|
|
|
|||
|
|
@ -41,17 +41,21 @@ class LAYPixelBuffer_TestClass < TestBase
|
|||
|
||||
def test_1
|
||||
|
||||
pb = RBA::PixelBuffer::new
|
||||
assert_equal(pb.width, 0)
|
||||
assert_equal(pb.height, 0)
|
||||
pb_null = RBA::PixelBuffer::new
|
||||
assert_equal(pb_null.width, 0)
|
||||
assert_equal(pb_null.height, 0)
|
||||
|
||||
pb = RBA::PixelBuffer::new(10, 20)
|
||||
assert_equal(compare(pb_null, pb), false)
|
||||
assert_equal(pb_null == pb, false)
|
||||
assert_equal(pb.width, 10)
|
||||
assert_equal(pb.height, 20)
|
||||
assert_equal(pb.transparent, false)
|
||||
|
||||
pb_copy = pb.dup
|
||||
pb.transparent = true
|
||||
assert_equal(pb.transparent, true)
|
||||
assert_equal(pb_copy == pb, false)
|
||||
|
||||
pb.fill(0xf0010203)
|
||||
assert_equal(pb.pixel(0, 0), 0xf0010203)
|
||||
|
|
@ -66,12 +70,14 @@ class LAYPixelBuffer_TestClass < TestBase
|
|||
|
||||
pb_copy = pb.dup
|
||||
assert_equal(compare(pb_copy, pb), true)
|
||||
assert_equal(pb_copy == pb, true)
|
||||
pb.set_pixel(1, 2, 0x112233)
|
||||
assert_equal(pb.pixel(0, 0), 0xf0010203)
|
||||
assert_equal(pb.pixel(1, 2), 0xff112233)
|
||||
assert_equal(pb_copy.pixel(1, 2), 0xff102030)
|
||||
|
||||
assert_equal(compare(pb_copy, pb), false)
|
||||
assert_equal(pb_copy == pb, false)
|
||||
|
||||
pb_copy.swap(pb)
|
||||
assert_equal(pb_copy.pixel(1, 2), 0xff112233)
|
||||
|
|
@ -88,14 +94,40 @@ class LAYPixelBuffer_TestClass < TestBase
|
|||
pb.set_pixel(1, 2, 0x112233)
|
||||
|
||||
assert_equal(compare(pb1, pb), false)
|
||||
assert_equal(pb1 == pb, false)
|
||||
|
||||
diff = pb1.diff(pb)
|
||||
pb1.patch(diff)
|
||||
assert_equal(compare(pb1, pb), true)
|
||||
assert_equal(pb1 == pb, true)
|
||||
|
||||
end
|
||||
|
||||
def test_3
|
||||
|
||||
pb = RBA::PixelBuffer::new(10, 20)
|
||||
pb.fill(0xf0010203)
|
||||
|
||||
pb1 = pb.dup
|
||||
pb.set_pixel(1, 2, 0x112233)
|
||||
|
||||
pb1 = pb.dup
|
||||
pb.set_pixel(1, 2, 0xf0112233)
|
||||
assert_equal(compare(pb1, pb), true)
|
||||
assert_equal(pb1 == pb, true) # not transparent -> alpha is ignored
|
||||
|
||||
pb1.transparent = true
|
||||
pb.transparent = true
|
||||
assert_equal(compare(pb1, pb), true)
|
||||
assert_equal(pb1 == pb, true)
|
||||
|
||||
pb.set_pixel(1, 2, 0xf0112233)
|
||||
assert_equal(compare(pb1, pb), false)
|
||||
assert_equal(pb1 == pb, false) # now, alpha matters
|
||||
|
||||
end
|
||||
|
||||
def test_4
|
||||
|
||||
pb = RBA::PixelBuffer::new(10, 20)
|
||||
pb.transparent = true
|
||||
|
|
|
|||
Loading…
Reference in New Issue