Fix image conversion from Indexed to Indexed mapping colors (related to issue #267 and #195)

This commit is contained in:
David Capello 2014-03-29 21:31:27 -03:00
parent 6262366e91
commit c1e26d0ac0
2 changed files with 51 additions and 11 deletions

View File

@ -185,19 +185,27 @@ void clipboard::paste()
}
#endif
Sprite* sprite = editor->getDocument()->getSprite();
Sprite* dst_sprite = editor->getDocument()->getSprite();
if (clipboard_image == NULL)
return;
Palette* dst_palette = dst_sprite->getPalette(editor->getFrame());
// Source image (clipboard or a converted copy to the destination 'imgtype')
Image* src_image;
if (clipboard_image->getPixelFormat() == sprite->getPixelFormat())
if (clipboard_image->getPixelFormat() == dst_sprite->getPixelFormat() &&
// Indexed images can be copied directly only if both images
// have the same palette.
(clipboard_image->getPixelFormat() != IMAGE_INDEXED ||
clipboard_palette->countDiff(dst_palette, NULL, NULL) == 0)) {
src_image = clipboard_image;
}
else {
RgbMap* rgbmap = sprite->getRgbMap(editor->getFrame());
RgbMap* dst_rgbmap = dst_sprite->getRgbMap(editor->getFrame());
src_image = quantization::convert_pixel_format(
clipboard_image, sprite->getPixelFormat(),
DITHERING_NONE, rgbmap, clipboard_palette,
clipboard_image, dst_sprite->getPixelFormat(),
DITHERING_NONE, dst_rgbmap, clipboard_palette,
false);
}

View File

@ -91,13 +91,10 @@ Image* convert_pixel_format(const Image* image,
const Palette* palette,
bool has_background_layer)
{
// no convertion
if (image->getPixelFormat() == pixelFormat)
return NULL;
// RGB -> Indexed with ordered dithering
else if (image->getPixelFormat() == IMAGE_RGB &&
pixelFormat == IMAGE_INDEXED &&
ditheringMethod == DITHERING_ORDERED) {
if (image->getPixelFormat() == IMAGE_RGB &&
pixelFormat == IMAGE_INDEXED &&
ditheringMethod == DITHERING_ORDERED) {
return ordered_dithering(image, 0, 0, rgbmap, palette);
}
@ -113,6 +110,11 @@ Image* convert_pixel_format(const Image* image,
switch (new_image->getPixelFormat()) {
// RGB -> RGB
case IMAGE_RGB:
new_image->copy(image, 0, 0);
break;
// RGB -> Grayscale
case IMAGE_GRAYSCALE: {
LockImageBits<GrayscaleTraits> dstBits(new_image, Image::WriteLock);
@ -144,6 +146,7 @@ Image* convert_pixel_format(const Image* image,
r = rgba_getr(c);
g = rgba_getg(c);
b = rgba_getb(c);
if (rgba_geta(c) == 0)
*dst_it = 0;
else
@ -179,6 +182,11 @@ Image* convert_pixel_format(const Image* image,
break;
}
// Grayscale -> Grayscale
case IMAGE_GRAYSCALE:
new_image->copy(image, 0, 0);
break;
// Grayscale -> Indexed
case IMAGE_INDEXED: {
LockImageBits<IndexedTraits> dstBits(new_image, Image::WriteLock);
@ -250,6 +258,30 @@ Image* convert_pixel_format(const Image* image,
break;
}
// Indexed -> Indexed
case IMAGE_INDEXED: {
LockImageBits<IndexedTraits> dstBits(new_image, Image::WriteLock);
LockImageBits<IndexedTraits>::iterator dst_it = dstBits.begin(), dst_end = dstBits.end();
color_t dstMaskColor = new_image->getMaskColor();
for (; src_it != src_end; ++src_it, ++dst_it) {
ASSERT(dst_it != dst_end);
c = *src_it;
if (c == image->getMaskColor())
*dst_it = dstMaskColor;
else {
r = rgba_getr(palette->getEntry(c));
g = rgba_getg(palette->getEntry(c));
b = rgba_getb(palette->getEntry(c));
*dst_it = rgbmap->mapColor(r, g, b);
}
}
ASSERT(dst_it == dst_end);
break;
}
}
break;
}