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:
David Capello 2014-08-09 21:33:38 -03:00
parent 93c6967409
commit 2c675bfc4f
6 changed files with 82 additions and 23 deletions

View File

@ -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;
};

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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");

View File

@ -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