mirror of https://github.com/aseprite/aseprite.git
Merge 3efd0014e8
into fae42dbe12
This commit is contained in:
commit
86e920f6f5
|
@ -1050,7 +1050,47 @@ public:
|
|||
m_fop->newBlend(),
|
||||
RgbMapAlgorithm::OCTREE, // TODO configurable?
|
||||
false); // Do not add the transparent color yet
|
||||
m_transparentIndex = 0;
|
||||
m_globalColormapPalette = newPalette;
|
||||
m_globalColormap = createColorMap(&m_globalColormapPalette);
|
||||
}
|
||||
}
|
||||
|
||||
// The following "if" block is intended to address cases where
|
||||
// the Color Mode of the animation is RGB and can be represented by
|
||||
// an absolute palette because it contains fewer than 256 colors
|
||||
// throughout the entire animation. In this way the memory space
|
||||
// used to generate the GIF is much more efficient, since local
|
||||
// palettes don't need to be inserted in each frame. It also
|
||||
// fixes a display issue with GIF files (generated by
|
||||
// Aseprite 1.3.13) on Discord when the GIF parameters were:
|
||||
// - disposal = DO_NOT_DISPOSE = 1
|
||||
// - Local palettes exist.
|
||||
if (m_spec.colorMode() == ColorMode::RGB || m_spec.colorMode() == ColorMode::GRAYSCALE) {
|
||||
Palette newPalette(0, 512);
|
||||
render::create_palette_from_sprite(m_sprite,
|
||||
0,
|
||||
totalFrames() - 1,
|
||||
false,
|
||||
&newPalette,
|
||||
nullptr,
|
||||
m_fop->newBlend(),
|
||||
RgbMapAlgorithm::OCTREE,
|
||||
false); // No effect on OctreeMap.
|
||||
// Case: palette with (256 colors + mask color) == 257 but
|
||||
// the mask color isn't used in the sprite.
|
||||
if (newPalette.size() == 257 && !m_sprite->isColorUsed(0)) {
|
||||
// Forcing GIF with background
|
||||
m_transparentIndex = -1;
|
||||
m_hasBackground = true;
|
||||
// Discard the mask color (palette entry = 0)
|
||||
for (int i = 0; i < 256; i++)
|
||||
newPalette.setEntry(i, newPalette.getEntry(i + 1));
|
||||
newPalette.resize(256);
|
||||
m_globalColormapPalette = newPalette;
|
||||
m_globalColormap = createColorMap(&m_globalColormapPalette);
|
||||
}
|
||||
else if (newPalette.size() <= 256) {
|
||||
m_transparentIndex = 0;
|
||||
m_globalColormapPalette = newPalette;
|
||||
m_globalColormap = createColorMap(&m_globalColormapPalette);
|
||||
|
@ -1391,15 +1431,18 @@ private:
|
|||
|
||||
if (!m_preservePaletteOrder) {
|
||||
const LockImageBits<RgbTraits> srcBits(m_deltaImage.get());
|
||||
const LockImageBits<RgbTraits> preBits(m_previousImage, frameBounds);
|
||||
LockImageBits<IndexedTraits> dstBits(frameImage.get());
|
||||
|
||||
auto srcIt = srcBits.begin();
|
||||
auto dstIt = dstBits.begin();
|
||||
auto preIt = preBits.begin();
|
||||
|
||||
for (int y = 0; y < frameBounds.h; ++y) {
|
||||
for (int x = 0; x < frameBounds.w; ++x, ++srcIt, ++dstIt) {
|
||||
for (int x = 0; x < frameBounds.w; ++x, ++srcIt, ++dstIt, ++preIt) {
|
||||
ASSERT(srcIt != srcBits.end());
|
||||
ASSERT(dstIt != dstBits.end());
|
||||
ASSERT(preIt != preBits.end());
|
||||
|
||||
color_t color = *srcIt;
|
||||
int i;
|
||||
|
@ -1413,9 +1456,19 @@ private:
|
|||
if (i < 0)
|
||||
i = octree.mapColor(color | rgba_a_mask); // alpha=255
|
||||
}
|
||||
// If the alpha in a pixel from m_deltaImage is < 128, the
|
||||
// pixel is assumed to be 0. Then it should draw the pixel
|
||||
// according defined m_transparentIndex or disposal method
|
||||
else {
|
||||
if (m_transparentIndex >= 0)
|
||||
i = m_transparentIndex;
|
||||
else if (disposal == DisposalMethod::DO_NOT_DISPOSE) {
|
||||
i = framePalette.findExactMatch(rgba_getr(*preIt),
|
||||
rgba_getg(*preIt),
|
||||
rgba_getb(*preIt),
|
||||
255,
|
||||
-1);
|
||||
}
|
||||
else
|
||||
i = m_bgIndex;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Aseprite Document Library
|
||||
// Copyright (c) 2018-2023 Igara Studio S.A.
|
||||
// Copyright (c) 2018-2025 Igara Studio S.A.
|
||||
// Copyright (c) 2001-2016 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
|
@ -352,6 +352,18 @@ bool is_plain_image_templ(const Image* img, const color_t color)
|
|||
return true;
|
||||
}
|
||||
|
||||
template<typename ImageTraits>
|
||||
bool is_color_used_templ(const Image* img, const doc::color_t color)
|
||||
{
|
||||
const LockImageBits<ImageTraits> bits(img);
|
||||
auto it = bits.begin(), end = bits.end();
|
||||
for (; it != end; ++it) {
|
||||
if (*it == color)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename ImageTraits>
|
||||
int count_diff_between_images_templ(const Image* i1, const Image* i2)
|
||||
{
|
||||
|
@ -464,6 +476,16 @@ bool is_plain_image(const Image* img, color_t c)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool is_color_used(const Image* img, color_t c)
|
||||
{
|
||||
ASSERT(img->pixelFormat() == IMAGE_RGB || img->pixelFormat() == IMAGE_GRAYSCALE);
|
||||
switch (img->pixelFormat()) {
|
||||
case IMAGE_RGB: return is_color_used_templ<RgbTraits>(img, c);
|
||||
case IMAGE_GRAYSCALE: return is_color_used_templ<GrayscaleTraits>(img, c);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_empty_image(const Image* img)
|
||||
{
|
||||
color_t c = 0; // alpha = 0
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Aseprite Document Library
|
||||
// Copyright (c) 2018-2023 Igara Studio S.A.
|
||||
// Copyright (c) 2018-2025 Igara Studio S.A.
|
||||
// Copyright (c) 2001-2016 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
|
@ -65,6 +65,7 @@ void fill_ellipse(Image* image,
|
|||
color_t color);
|
||||
|
||||
bool is_plain_image(const Image* img, color_t c);
|
||||
bool is_color_used(const Image* img, color_t c);
|
||||
bool is_empty_image(const Image* img);
|
||||
|
||||
int count_diff_between_images(const Image* i1, const Image* i2);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Aseprite Document Library
|
||||
// Copyright (C) 2018-2024 Igara Studio S.A.
|
||||
// Copyright (C) 2018-2025 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
|
@ -223,6 +223,18 @@ bool Sprite::isOpaque() const
|
|||
return (bg && bg->isVisible());
|
||||
}
|
||||
|
||||
bool Sprite::isColorUsed(const doc::color_t c) const
|
||||
{
|
||||
ASSERT(pixelFormat() == IMAGE_RGB || pixelFormat() == IMAGE_GRAYSCALE);
|
||||
for (Cel* cel : cels()) {
|
||||
if (cel && cel->image()) {
|
||||
if (is_color_used(cel->image(), c))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Sprite::needAlpha() const
|
||||
{
|
||||
switch (pixelFormat()) {
|
||||
|
|
|
@ -110,6 +110,9 @@ public:
|
|||
// Returns true if the sprite has a background layer and it's visible
|
||||
bool isOpaque() const;
|
||||
|
||||
// Returns true if the sprite is using a pixel with color c
|
||||
bool isColorUsed(const doc::color_t c) const;
|
||||
|
||||
// Returns true if the rendered images will contain alpha values less
|
||||
// than 255. Only RGBA and Grayscale images without background needs
|
||||
// alpha channel in the render.
|
||||
|
|
Loading…
Reference in New Issue