lua: Add Image:isEqual()

This commit is contained in:
David Capello 2018-11-13 12:52:51 -03:00
parent d20436f957
commit dea603753b
5 changed files with 84 additions and 3 deletions

View File

@ -176,6 +176,16 @@ int Image_getPixel(lua_State* L)
return 1;
}
int Image_isEqual(lua_State* L)
{
auto objA = get_obj<ImageObj>(L, 1);
auto objB = get_obj<ImageObj>(L, 2);
bool res = doc::is_same_image(objA->image.get(),
objB->image.get());
lua_pushboolean(L, res);
return 1;
}
int Image_get_width(lua_State* L)
{
const auto obj = get_obj<ImageObj>(L, 1);
@ -211,6 +221,7 @@ const luaL_Reg Image_methods[] = {
{ "putImage", Image_putImage },
{ "putSprite", Image_putSprite },
{ "pixels", Image_pixels },
{ "isEqual", Image_isEqual },
{ "__gc", Image_gc },
{ nullptr, nullptr }
};

View File

@ -64,7 +64,7 @@ int Selection_eq(lua_State* L)
const bool result =
(a->mask->isEmpty() && b->mask->isEmpty()) ||
(!a->mask->isEmpty() && !b->mask->isEmpty() &&
count_diff_between_images(a->mask->bitmap(), b->mask->bitmap()) == 0);
is_same_image(a->mask->bitmap(), b->mask->bitmap()));
lua_pushboolean(L, result);
return 1;
}

View File

@ -10,6 +10,7 @@
#pragma once
#include "doc/blend_funcs.h"
#include "doc/color.h"
#include "doc/color_mode.h"
#include "doc/pixel_format.h"
@ -41,6 +42,19 @@ namespace doc {
static inline BlendFunc get_blender(BlendMode blend_mode) {
return get_rgba_blender(blend_mode);
}
static inline bool same_color(const pixel_t a, const pixel_t b) {
if (rgba_geta(a) == 0) {
if (rgba_geta(b) == 0)
return true;
else
return false;
}
else if (rgba_geta(b) == 0)
return false;
else
return a == b;
}
};
struct GrayscaleTraits {
@ -69,6 +83,19 @@ namespace doc {
static inline BlendFunc get_blender(BlendMode blend_mode) {
return get_graya_blender(blend_mode);
}
static inline bool same_color(const pixel_t a, const pixel_t b) {
if (graya_geta(a) == 0) {
if (graya_geta(b) == 0)
return true;
else
return false;
}
else if (graya_geta(b) == 0)
return false;
else
return a == b;
}
};
struct IndexedTraits {
@ -97,6 +124,10 @@ namespace doc {
static inline BlendFunc get_blender(BlendMode blend_mode) {
return get_indexed_blender(blend_mode);
}
static inline bool same_color(const pixel_t a, const pixel_t b) {
return a == b;
}
};
struct BitmapTraits {
@ -121,6 +152,10 @@ namespace doc {
static inline int getRowStrideBytes(int pixels_per_row) {
return ((pixels_per_row+7) / 8);
}
static inline bool same_color(const pixel_t a, const pixel_t b) {
return a == b;
}
};
} // namespace doc

View File

@ -319,15 +319,31 @@ int count_diff_between_images_templ(const Image* i1, const Image* i2)
for (it1 = bits1.begin(), end1 = bits1.end(),
it2 = bits2.begin(), end2 = bits2.end();
it1 != end1 && it2 != end2; ++it1, ++it2) {
if (*it1 != *it2)
if (!ImageTraits::same_color(*it1, *it2))
diff++;
}
ASSERT(it1 == end1);
ASSERT(it2 == end2);
return diff;
}
template<typename ImageTraits>
int is_same_image_templ(const Image* i1, const Image* i2)
{
const LockImageBits<ImageTraits> bits1(i1);
const LockImageBits<ImageTraits> bits2(i2);
typename LockImageBits<ImageTraits>::const_iterator it1, it2, end1, end2;
for (it1 = bits1.begin(), end1 = bits1.end(),
it2 = bits2.begin(), end2 = bits2.end();
it1 != end1 && it2 != end2; ++it1, ++it2) {
if (!ImageTraits::same_color(*it1, *it2))
return false;
}
ASSERT(it1 == end1);
ASSERT(it2 == end2);
return true;
}
} // anonymous namespace
bool is_plain_image(const Image* img, color_t c)
@ -367,6 +383,24 @@ int count_diff_between_images(const Image* i1, const Image* i2)
return -1;
}
bool is_same_image(const Image* i1, const Image* i2)
{
if ((i1->pixelFormat() != i2->pixelFormat()) ||
(i1->width() != i2->width()) ||
(i1->height() != i2->height()))
return false;
switch (i1->pixelFormat()) {
case IMAGE_RGB: return is_same_image_templ<RgbTraits>(i1, i2);
case IMAGE_GRAYSCALE: return is_same_image_templ<GrayscaleTraits>(i1, i2);
case IMAGE_INDEXED: return is_same_image_templ<IndexedTraits>(i1, i2);
case IMAGE_BITMAP: return is_same_image_templ<BitmapTraits>(i1, i2);
}
ASSERT(false);
return false;
}
void remap_image(Image* image, const Remap& remap)
{
ASSERT(image->pixelFormat() == IMAGE_INDEXED);

View File

@ -44,6 +44,7 @@ namespace doc {
bool is_empty_image(const Image* img);
int count_diff_between_images(const Image* i1, const Image* i2);
bool is_same_image(const Image* i1, const Image* i2);
void remap_image(Image* image, const Remap& remap);