mirror of
https://github.com/aseprite/aseprite.git
synced 2025-02-28 16:11:35 +00:00
Fix crash in PreviewCommand
We cannot use the ui::Graphics internal surface directly when we use raster::convert_image_to_surface() (it expects an Rgba surface).
This commit is contained in:
parent
93c6967409
commit
2c675bfc4f
@ -39,6 +39,9 @@
|
||||
#include "raster/palette.h"
|
||||
#include "raster/primitives.h"
|
||||
#include "raster/sprite.h"
|
||||
#include "she/scoped_handle.h"
|
||||
#include "she/surface.h"
|
||||
#include "she/system.h"
|
||||
|
||||
#define PREVIEW_TILED 1
|
||||
#define PREVIEW_FIT_ON_SCREEN 2
|
||||
@ -59,7 +62,8 @@ public:
|
||||
, m_sprite(editor->sprite())
|
||||
, m_pal(m_sprite->getPalette(editor->frame()))
|
||||
, m_index_bg_color(-1)
|
||||
, m_doublebuf(Image::create(IMAGE_RGB, JI_SCREEN_W, JI_SCREEN_H)) {
|
||||
, m_doublebuf(Image::create(IMAGE_RGB, JI_SCREEN_W, JI_SCREEN_H))
|
||||
, m_doublesur(she::instance()->createRgbaSurface(JI_SCREEN_W, JI_SCREEN_H)) {
|
||||
// Do not use DocumentWriter (do not lock the document) because we
|
||||
// will call other sub-commands (e.g. previous frame, next frame,
|
||||
// etc.).
|
||||
@ -230,7 +234,9 @@ protected:
|
||||
break;
|
||||
}
|
||||
|
||||
raster::convert_image_to_surface(m_doublebuf, g->getInternalSurface(), 0, 0, m_pal);
|
||||
raster::convert_image_to_surface(m_doublebuf, m_pal,
|
||||
m_doublesur, 0, 0, 0, 0, m_doublebuf->width(), m_doublebuf->height());
|
||||
g->blit(m_doublesur, 0, 0, 0, 0, m_doublesur->width(), m_doublesur->height());
|
||||
}
|
||||
|
||||
private:
|
||||
@ -247,6 +253,7 @@ private:
|
||||
int m_index_bg_color;
|
||||
base::UniquePtr<Image> m_render;
|
||||
base::UniquePtr<Image> m_doublebuf;
|
||||
she::ScopedHandle<she::Surface> m_doublesur;
|
||||
filters::TiledMode m_tiled;
|
||||
};
|
||||
|
||||
|
@ -112,7 +112,8 @@ private:
|
||||
m_thumbnail->width(),
|
||||
m_thumbnail->height());
|
||||
|
||||
convert_image_to_surface(m_thumbnail, thumbnail, 0, 0, m_palette);
|
||||
convert_image_to_surface(m_thumbnail, m_palette, thumbnail,
|
||||
0, 0, 0, 0, m_thumbnail->width(), m_thumbnail->height());
|
||||
|
||||
m_fileitem->setThumbnail(thumbnail);
|
||||
}
|
||||
|
@ -102,7 +102,8 @@ public:
|
||||
m_bitmap->dispose();
|
||||
|
||||
m_bitmap = she::instance()->createRgbaSurface(image->width(), image->height());
|
||||
convert_image_to_surface(image, m_bitmap, 0, 0, palette);
|
||||
convert_image_to_surface(image, palette, m_bitmap,
|
||||
0, 0, 0, 0, image->width(), image->height());
|
||||
|
||||
invalidate();
|
||||
}
|
||||
|
@ -399,7 +399,8 @@ void Editor::drawOneSpriteUnclippedRect(ui::Graphics* g, const gfx::Rect& rc, in
|
||||
}
|
||||
|
||||
she::Surface* tmp(she::instance()->createRgbaSurface(width, height));
|
||||
convert_image_to_surface(rendered, tmp, 0, 0, m_sprite->getPalette(m_frame));
|
||||
convert_image_to_surface(rendered, m_sprite->getPalette(m_frame),
|
||||
tmp, 0, 0, 0, 0, width, height);
|
||||
g->blit(tmp, 0, 0, dest_x, dest_y, width, height);
|
||||
tmp->dispose();
|
||||
}
|
||||
|
@ -85,15 +85,14 @@ uint32_t convert_color_to_surface<BitmapTraits, she::kRgbaSurfaceFormat>(color_t
|
||||
}
|
||||
|
||||
template<typename ImageTraits, typename AddressType>
|
||||
void convert_image_to_surface_templ(const Image* image, she::LockedSurface* dst, int x, int y, const Palette* palette, const she::SurfaceFormatData* fd)
|
||||
void convert_image_to_surface_templ(const Image* image, she::LockedSurface* dst,
|
||||
int src_x, int src_y, int dst_x, int dst_y, int w, int h, const Palette* palette, const she::SurfaceFormatData* fd)
|
||||
{
|
||||
const LockImageBits<ImageTraits> bits(image);
|
||||
const LockImageBits<ImageTraits> bits(image, gfx::Rect(src_x, src_y, w, h));
|
||||
typename LockImageBits<ImageTraits>::const_iterator src_it = bits.begin(), src_end = bits.end();
|
||||
int w = image->width();
|
||||
int h = image->height();
|
||||
|
||||
for (int v=0; v<h; ++v) {
|
||||
AddressType dst_address = AddressType(dst->getData(x, y));
|
||||
for (int v=0; v<h; ++v, ++dst_y) {
|
||||
AddressType dst_address = AddressType(dst->getData(dst_x, dst_y));
|
||||
for (int u=0; u<w; ++u) {
|
||||
ASSERT(src_it != src_end);
|
||||
|
||||
@ -101,7 +100,6 @@ void convert_image_to_surface_templ(const Image* image, she::LockedSurface* dst,
|
||||
++dst_address;
|
||||
++src_it;
|
||||
}
|
||||
++y;
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,30 +116,79 @@ struct Address24bpp
|
||||
};
|
||||
|
||||
template<typename ImageTraits>
|
||||
void convert_image_to_surface_selector(const Image* image, she::LockedSurface* surface, int x, int y, const Palette* palette, const she::SurfaceFormatData* fd)
|
||||
void convert_image_to_surface_selector(const Image* image, she::LockedSurface* surface,
|
||||
int src_x, int src_y, int dst_x, int dst_y, int w, int h, const Palette* palette, const she::SurfaceFormatData* fd)
|
||||
{
|
||||
switch (fd->bitsPerPixel) {
|
||||
case 8: convert_image_to_surface_templ<ImageTraits, uint8_t*>(image, surface, x, y, palette, fd); break;
|
||||
|
||||
case 8:
|
||||
convert_image_to_surface_templ<ImageTraits, uint8_t*>(image, surface, src_x, src_y, dst_x, dst_y, w, h, palette, fd);
|
||||
break;
|
||||
|
||||
case 15:
|
||||
case 16: convert_image_to_surface_templ<ImageTraits, uint16_t*>(image, surface, x, y, palette, fd); break;
|
||||
case 24: convert_image_to_surface_templ<ImageTraits, Address24bpp>(image, surface, x, y, palette, fd); break;
|
||||
case 32: convert_image_to_surface_templ<ImageTraits, uint32_t*>(image, surface, x, y, palette, fd); break;
|
||||
case 16:
|
||||
convert_image_to_surface_templ<ImageTraits, uint16_t*>(image, surface, src_x, src_y, dst_x, dst_y, w, h, palette, fd);
|
||||
break;
|
||||
|
||||
case 24:
|
||||
convert_image_to_surface_templ<ImageTraits, Address24bpp>(image, surface, src_x, src_y, dst_x, dst_y, w, h, palette, fd);
|
||||
break;
|
||||
|
||||
case 32:
|
||||
convert_image_to_surface_templ<ImageTraits, uint32_t*>(image, surface, src_x, src_y, dst_x, dst_y, w, h, palette, fd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
void convert_image_to_surface(const Image* image, she::Surface* surface, int x, int y, const Palette* palette)
|
||||
void convert_image_to_surface(const Image* image, const Palette* palette,
|
||||
she::Surface* surface, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
|
||||
{
|
||||
gfx::Rect srcBounds(src_x, src_y, w, h);
|
||||
srcBounds = srcBounds.createIntersect(image->bounds());
|
||||
if (srcBounds.isEmpty())
|
||||
return;
|
||||
|
||||
src_x = srcBounds.x;
|
||||
src_y = srcBounds.y;
|
||||
w = srcBounds.w;
|
||||
h = srcBounds.h;
|
||||
|
||||
gfx::Rect dstBounds(dst_x, dst_y, w, h);
|
||||
dstBounds = dstBounds.createIntersect(surface->getClipBounds());
|
||||
if (dstBounds.isEmpty())
|
||||
return;
|
||||
|
||||
src_x += dstBounds.x - dst_x;
|
||||
src_y += dstBounds.y - dst_y;
|
||||
dst_x = dstBounds.x;
|
||||
dst_y = dstBounds.y;
|
||||
w = dstBounds.w;
|
||||
h = dstBounds.h;
|
||||
|
||||
she::ScopedSurfaceLock dst(surface);
|
||||
she::SurfaceFormatData fd;
|
||||
dst->getFormat(&fd);
|
||||
|
||||
switch (image->pixelFormat()) {
|
||||
case IMAGE_RGB: convert_image_to_surface_selector<RgbTraits>(image, dst, x, y, palette, &fd); break;
|
||||
case IMAGE_GRAYSCALE: convert_image_to_surface_selector<GrayscaleTraits>(image, dst, x, y, palette, &fd); break;
|
||||
case IMAGE_INDEXED: convert_image_to_surface_selector<IndexedTraits>(image, dst, x, y, palette, &fd); break;
|
||||
case IMAGE_BITMAP: convert_image_to_surface_selector<BitmapTraits>(image, dst, x, y, palette, &fd); break;
|
||||
|
||||
case IMAGE_RGB:
|
||||
convert_image_to_surface_selector<RgbTraits>(image, dst, src_x, src_y, dst_x, dst_y, w, h, palette, &fd);
|
||||
break;
|
||||
|
||||
case IMAGE_GRAYSCALE:
|
||||
convert_image_to_surface_selector<GrayscaleTraits>(image, dst, src_x, src_y, dst_x, dst_y, w, h, palette, &fd);
|
||||
break;
|
||||
|
||||
case IMAGE_INDEXED:
|
||||
convert_image_to_surface_selector<IndexedTraits>(image, dst, src_x, src_y, dst_x, dst_y, w, h, palette, &fd);
|
||||
break;
|
||||
|
||||
case IMAGE_BITMAP:
|
||||
convert_image_to_surface_selector<BitmapTraits>(image, dst, src_x, src_y, dst_x, dst_y, w, h, palette, &fd);
|
||||
break;
|
||||
|
||||
default:
|
||||
ASSERT(false);
|
||||
throw std::runtime_error("conversion not supported");
|
||||
|
@ -28,7 +28,9 @@ namespace raster {
|
||||
class Image;
|
||||
class Palette;
|
||||
|
||||
void convert_image_to_surface(const Image* image, she::Surface* surface, int x, int y, const Palette* palette);
|
||||
void convert_image_to_surface(const Image* image, const Palette* palette,
|
||||
she::Surface* surface,
|
||||
int src_x, int src_y, int dst_x, int dst_y, int w, int h);
|
||||
|
||||
} // namespace raster
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user