mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-29 21:33:12 +00:00
Fixed critical bugs in rendering code with zoom.
This commit is contained in:
parent
a67c563d6f
commit
a872edd377
@ -1,3 +1,9 @@
|
||||
2009-08-02 David A. Capello <davidcapello@gmail.com>
|
||||
|
||||
* src/util/render.cpp (merge_zoomed_image): unified all
|
||||
merge_zoomed_image8/16/32 in one generic method (and fixed
|
||||
critical bugs).
|
||||
|
||||
2009-06-14 David A. Capello <davidcapello@gmail.com>
|
||||
|
||||
* src/commands/cmd_rotate_canvas.cpp: Added.
|
||||
|
@ -181,6 +181,7 @@ COMMON_SOURCES = \
|
||||
src/raster/dirty.cpp \
|
||||
src/raster/gfxobj.cpp \
|
||||
src/raster/image.cpp \
|
||||
src/raster/image_impl.cpp \
|
||||
src/raster/layer.cpp \
|
||||
src/raster/mask.cpp \
|
||||
src/raster/palette.cpp \
|
||||
|
539
src/raster/image_impl.cpp
Normal file
539
src/raster/image_impl.cpp
Normal file
@ -0,0 +1,539 @@
|
||||
/* ASE - Allegro Sprite Editor
|
||||
* Copyright (C) 2001-2009 David Capello
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "raster/image_impl.h"
|
||||
|
||||
template<>
|
||||
void ImageImpl<RgbTraits>::to_allegro(BITMAP *bmp, int _x, int _y) const
|
||||
{
|
||||
const_address_t addr = raw_pixels();
|
||||
unsigned long bmp_address;
|
||||
int depth = bitmap_color_depth(bmp);
|
||||
int x, y;
|
||||
|
||||
bmp_select(bmp);
|
||||
|
||||
switch (depth) {
|
||||
|
||||
case 8:
|
||||
#if defined GFX_MODEX && !defined ALLEGRO_UNIX
|
||||
if (is_planar_bitmap(bmp)) {
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = (unsigned long)bmp->line[_y];
|
||||
|
||||
for (x=0; x<image->w; x++) {
|
||||
outportw(0x3C4, (0x100<<((_x+x)&3))|2);
|
||||
bmp_write8(bmp_address+((_x+x)>>2),
|
||||
makecol8((*addr) & 0xff,
|
||||
((*addr)>>8) & 0xff,
|
||||
((*addr)>>16) & 0xff));
|
||||
addr++;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write8(bmp_address,
|
||||
makecol8((*addr) & 0xff,
|
||||
((*addr)>>8) & 0xff,
|
||||
((*addr)>>16) & 0xff));
|
||||
addr++;
|
||||
bmp_address++;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
#if defined GFX_MODEX && !defined ALLEGRO_UNIX
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 15:
|
||||
_x <<= 1;
|
||||
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write15(bmp_address,
|
||||
makecol15((*addr) & 0xff,
|
||||
((*addr)>>8) & 0xff,
|
||||
((*addr)>>16) & 0xff));
|
||||
addr++;
|
||||
bmp_address += 2;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 16:
|
||||
_x <<= 1;
|
||||
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = bmp_write_line (bmp, _y)+_x;
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write16(bmp_address,
|
||||
makecol16((*addr) & 0xff,
|
||||
((*addr)>>8) & 0xff,
|
||||
((*addr)>>16) & 0xff));
|
||||
addr++;
|
||||
bmp_address += 2;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 24:
|
||||
_x *= 3;
|
||||
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write24(bmp_address,
|
||||
makecol24((*addr) & 0xff,
|
||||
((*addr)>>8) & 0xff,
|
||||
((*addr)>>16) & 0xff));
|
||||
addr++;
|
||||
bmp_address += 3;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 32:
|
||||
_x <<= 2;
|
||||
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write32(bmp_address,
|
||||
makeacol32((*addr) & 0xff,
|
||||
((*addr)>>8) & 0xff,
|
||||
((*addr)>>16) & 0xff,
|
||||
((*addr)>>24) & 0xff));
|
||||
addr++;
|
||||
bmp_address += 4;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
bmp_unwrite_line(bmp);
|
||||
}
|
||||
|
||||
template<>
|
||||
void ImageImpl<GrayscaleTraits>::to_allegro(BITMAP *bmp, int _x, int _y) const
|
||||
{
|
||||
const_address_t addr = raw_pixels();
|
||||
unsigned long bmp_address;
|
||||
int depth = bitmap_color_depth(bmp);
|
||||
int x, y;
|
||||
|
||||
bmp_select(bmp);
|
||||
|
||||
switch (depth) {
|
||||
|
||||
case 8:
|
||||
#if defined GFX_MODEX && !defined ALLEGRO_UNIX
|
||||
if (is_planar_bitmap(bmp)) {
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = (unsigned long)bmp->line[_y];
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
outportw(0x3C4, (0x100<<((_x+x)&3))|2);
|
||||
bmp_write8(bmp_address+((_x+x)>>2),
|
||||
_index_cmap[(*addr) & 0xff]);
|
||||
addr++;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write8(bmp_address, _index_cmap[(*addr) & 0xff]);
|
||||
addr++;
|
||||
bmp_address++;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
#if defined GFX_MODEX && !defined ALLEGRO_UNIX
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 15:
|
||||
_x <<= 1;
|
||||
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write15(bmp_address,
|
||||
makecol15((*addr) & 0xff,
|
||||
(*addr) & 0xff,
|
||||
(*addr) & 0xff));
|
||||
addr++;
|
||||
bmp_address += 2;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 16:
|
||||
_x <<= 1;
|
||||
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write16(bmp_address,
|
||||
makecol16((*addr) & 0xff,
|
||||
(*addr) & 0xff,
|
||||
(*addr) & 0xff));
|
||||
addr++;
|
||||
bmp_address += 2;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 24:
|
||||
_x *= 3;
|
||||
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write24(bmp_address,
|
||||
makecol24((*addr) & 0xff,
|
||||
(*addr) & 0xff,
|
||||
(*addr) & 0xff));
|
||||
addr++;
|
||||
bmp_address += 3;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 32:
|
||||
_x <<= 2;
|
||||
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write32(bmp_address,
|
||||
makeacol32((*addr) & 0xff,
|
||||
(*addr) & 0xff,
|
||||
(*addr) & 0xff, 255));
|
||||
addr++;
|
||||
bmp_address += 4;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
bmp_unwrite_line(bmp);
|
||||
}
|
||||
|
||||
template<>
|
||||
void ImageImpl<IndexedTraits>::to_allegro(BITMAP *bmp, int _x, int _y) const
|
||||
{
|
||||
#define RGB_TRIPLET \
|
||||
_rgb_scale_6[_current_palette[_index_cmap[(*addr)]].r], \
|
||||
_rgb_scale_6[_current_palette[_index_cmap[(*addr)]].g], \
|
||||
_rgb_scale_6[_current_palette[_index_cmap[(*addr)]].b]
|
||||
|
||||
const_address_t addr = raw_pixels();
|
||||
unsigned long bmp_address;
|
||||
int depth = bitmap_color_depth(bmp);
|
||||
int x, y;
|
||||
|
||||
bmp_select(bmp);
|
||||
|
||||
switch (depth) {
|
||||
|
||||
case 8:
|
||||
#if defined GFX_MODEX && !defined ALLEGRO_UNIX
|
||||
if (is_planar_bitmap (bmp)) {
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = (unsigned long)bmp->line[_y];
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
outportw(0x3C4, (0x100<<((_x+x)&3))|2);
|
||||
bmp_write8(bmp_address+((_x+x)>>2), _index_cmap[(*addr)]);
|
||||
address++;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write8(bmp_address, _index_cmap[(*addr)]);
|
||||
addr++;
|
||||
bmp_address++;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
#if defined GFX_MODEX && !defined ALLEGRO_UNIX
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 15:
|
||||
_x <<= 1;
|
||||
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write15(bmp_address, makecol15(RGB_TRIPLET));
|
||||
addr++;
|
||||
bmp_address += 2;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 16:
|
||||
_x <<= 1;
|
||||
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write16(bmp_address, makecol16(RGB_TRIPLET));
|
||||
addr++;
|
||||
bmp_address += 2;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 24:
|
||||
_x *= 3;
|
||||
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write24(bmp_address, makecol24(RGB_TRIPLET));
|
||||
addr++;
|
||||
bmp_address += 3;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 32:
|
||||
_x <<= 2;
|
||||
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write32(bmp_address, makeacol32(RGB_TRIPLET, 255));
|
||||
addr++;
|
||||
bmp_address += 4;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
bmp_unwrite_line(bmp);
|
||||
}
|
||||
|
||||
template<>
|
||||
void ImageImpl<BitmapTraits>::to_allegro(BITMAP *bmp, int _x, int _y) const
|
||||
{
|
||||
const_address_t addr;
|
||||
unsigned long bmp_address;
|
||||
int depth = bitmap_color_depth(bmp);
|
||||
div_t d, beg_d = div(0, 8);
|
||||
int color[2];
|
||||
int x, y;
|
||||
|
||||
bmp_select(bmp);
|
||||
|
||||
switch (depth) {
|
||||
|
||||
case 8:
|
||||
color[0] = makecol8(0, 0, 0);
|
||||
color[1] = makecol8(255, 255, 255);
|
||||
|
||||
#if defined GFX_MODEX && !defined ALLEGRO_UNIX
|
||||
if (is_planar_bitmap(bmp)) {
|
||||
for (y=0; y<h; y++) {
|
||||
addr = line_address(y);
|
||||
bmp_address = (unsigned long)bmp->line[_y];
|
||||
|
||||
d = beg_d;
|
||||
for (x=0; x<w; x++) {
|
||||
outportw (0x3C4, (0x100<<((_x+x)&3))|2);
|
||||
bmp_write8(bmp_addr+((_x+x)>>2),
|
||||
color[((*addr) & (1<<d.rem))? 1: 0]);
|
||||
_image_bitmap_next_bit(d, addr);
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
for (y=0; y<h; y++) {
|
||||
addr = line_address(y);
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
d = beg_d;
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write8 (bmp_address++, color[((*addr) & (1<<d.rem))? 1: 0]);
|
||||
_image_bitmap_next_bit(d, addr);
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
#if defined GFX_MODEX && !defined ALLEGRO_UNIX
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 15:
|
||||
color[0] = makecol15(0, 0, 0);
|
||||
color[1] = makecol15(255, 255, 255);
|
||||
|
||||
_x <<= 1;
|
||||
|
||||
for (y=0; y<h; y++) {
|
||||
addr = line_address(y);
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
d = beg_d;
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write15(bmp_address, color[((*addr) & (1<<d.rem))? 1: 0]);
|
||||
bmp_address += 2;
|
||||
_image_bitmap_next_bit(d, addr);
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 16:
|
||||
color[0] = makecol16(0, 0, 0);
|
||||
color[1] = makecol16(255, 255, 255);
|
||||
|
||||
_x <<= 1;
|
||||
|
||||
for (y=0; y<h; y++) {
|
||||
addr = line_address(y);
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
d = beg_d;
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write16(bmp_address, color[((*addr) & (1<<d.rem))? 1: 0]);
|
||||
bmp_address += 2;
|
||||
_image_bitmap_next_bit(d, addr);
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 24:
|
||||
color[0] = makecol24 (0, 0, 0);
|
||||
color[1] = makecol24 (255, 255, 255);
|
||||
|
||||
_x *= 3;
|
||||
|
||||
for (y=0; y<h; y++) {
|
||||
addr = line_address(y);
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
d = beg_d;
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write24(bmp_address, color[((*addr) & (1<<d.rem))? 1: 0]);
|
||||
bmp_address += 3;
|
||||
_image_bitmap_next_bit (d, addr);
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 32:
|
||||
color[0] = makeacol32 (0, 0, 0, 255);
|
||||
color[1] = makeacol32 (255, 255, 255, 255);
|
||||
|
||||
_x <<= 2;
|
||||
|
||||
for (y=0; y<h; y++) {
|
||||
addr = line_address(y);
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
d = beg_d;
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write32(bmp_address, color[((*addr) & (1<<d.rem))? 1: 0]);
|
||||
bmp_address += 4;
|
||||
_image_bitmap_next_bit(d, addr);
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
bmp_unwrite_line(bmp);
|
||||
}
|
@ -20,6 +20,9 @@
|
||||
#define RASTER_IMAGE_IMPL_H
|
||||
|
||||
#include <cassert>
|
||||
#include <allegro.h>
|
||||
|
||||
#include "raster/image.h"
|
||||
|
||||
template<class Traits>
|
||||
class ImageImpl : public Image
|
||||
@ -27,6 +30,8 @@ class ImageImpl : public Image
|
||||
typedef typename Traits::address_t address_t;
|
||||
typedef typename Traits::const_address_t const_address_t;
|
||||
|
||||
public: // raw access to pixel-data
|
||||
|
||||
inline address_t raw_pixels() {
|
||||
return (address_t)dat;
|
||||
}
|
||||
@ -44,7 +49,7 @@ class ImageImpl : public Image
|
||||
assert(y >= 0 && y < h);
|
||||
return ((const_address_t*)line)[y];
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
ImageImpl(int w, int h)
|
||||
@ -485,522 +490,4 @@ void ImageImpl<BitmapTraits>::merge(const Image* src, int x, int y, int opacity,
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
void ImageImpl<RgbTraits>::to_allegro(BITMAP *bmp, int _x, int _y) const
|
||||
{
|
||||
const_address_t addr = raw_pixels();
|
||||
unsigned long bmp_address;
|
||||
int depth = bitmap_color_depth(bmp);
|
||||
int x, y;
|
||||
|
||||
bmp_select(bmp);
|
||||
|
||||
switch (depth) {
|
||||
|
||||
case 8:
|
||||
#if defined GFX_MODEX && !defined ALLEGRO_UNIX
|
||||
if (is_planar_bitmap(bmp)) {
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = (unsigned long)bmp->line[_y];
|
||||
|
||||
for (x=0; x<image->w; x++) {
|
||||
outportw(0x3C4, (0x100<<((_x+x)&3))|2);
|
||||
bmp_write8(bmp_address+((_x+x)>>2),
|
||||
makecol8((*addr) & 0xff,
|
||||
((*addr)>>8) & 0xff,
|
||||
((*addr)>>16) & 0xff));
|
||||
addr++;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write8(bmp_address,
|
||||
makecol8((*addr) & 0xff,
|
||||
((*addr)>>8) & 0xff,
|
||||
((*addr)>>16) & 0xff));
|
||||
addr++;
|
||||
bmp_address++;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
#if defined GFX_MODEX && !defined ALLEGRO_UNIX
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 15:
|
||||
_x <<= 1;
|
||||
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write15(bmp_address,
|
||||
makecol15((*addr) & 0xff,
|
||||
((*addr)>>8) & 0xff,
|
||||
((*addr)>>16) & 0xff));
|
||||
addr++;
|
||||
bmp_address += 2;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 16:
|
||||
_x <<= 1;
|
||||
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = bmp_write_line (bmp, _y)+_x;
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write16(bmp_address,
|
||||
makecol16((*addr) & 0xff,
|
||||
((*addr)>>8) & 0xff,
|
||||
((*addr)>>16) & 0xff));
|
||||
addr++;
|
||||
bmp_address += 2;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 24:
|
||||
_x *= 3;
|
||||
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write24(bmp_address,
|
||||
makecol24((*addr) & 0xff,
|
||||
((*addr)>>8) & 0xff,
|
||||
((*addr)>>16) & 0xff));
|
||||
addr++;
|
||||
bmp_address += 3;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 32:
|
||||
_x <<= 2;
|
||||
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write32(bmp_address,
|
||||
makeacol32((*addr) & 0xff,
|
||||
((*addr)>>8) & 0xff,
|
||||
((*addr)>>16) & 0xff,
|
||||
((*addr)>>24) & 0xff));
|
||||
addr++;
|
||||
bmp_address += 4;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
bmp_unwrite_line(bmp);
|
||||
}
|
||||
|
||||
template<>
|
||||
void ImageImpl<GrayscaleTraits>::to_allegro(BITMAP *bmp, int _x, int _y) const
|
||||
{
|
||||
const_address_t addr = raw_pixels();
|
||||
unsigned long bmp_address;
|
||||
int depth = bitmap_color_depth(bmp);
|
||||
int x, y;
|
||||
|
||||
bmp_select(bmp);
|
||||
|
||||
switch (depth) {
|
||||
|
||||
case 8:
|
||||
#if defined GFX_MODEX && !defined ALLEGRO_UNIX
|
||||
if (is_planar_bitmap(bmp)) {
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = (unsigned long)bmp->line[_y];
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
outportw(0x3C4, (0x100<<((_x+x)&3))|2);
|
||||
bmp_write8(bmp_address+((_x+x)>>2),
|
||||
_index_cmap[(*addr) & 0xff]);
|
||||
addr++;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write8(bmp_address, _index_cmap[(*addr) & 0xff]);
|
||||
addr++;
|
||||
bmp_address++;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
#if defined GFX_MODEX && !defined ALLEGRO_UNIX
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 15:
|
||||
_x <<= 1;
|
||||
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write15(bmp_address,
|
||||
makecol15((*addr) & 0xff,
|
||||
(*addr) & 0xff,
|
||||
(*addr) & 0xff));
|
||||
addr++;
|
||||
bmp_address += 2;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 16:
|
||||
_x <<= 1;
|
||||
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write16(bmp_address,
|
||||
makecol16((*addr) & 0xff,
|
||||
(*addr) & 0xff,
|
||||
(*addr) & 0xff));
|
||||
addr++;
|
||||
bmp_address += 2;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 24:
|
||||
_x *= 3;
|
||||
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write24(bmp_address,
|
||||
makecol24((*addr) & 0xff,
|
||||
(*addr) & 0xff,
|
||||
(*addr) & 0xff));
|
||||
addr++;
|
||||
bmp_address += 3;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 32:
|
||||
_x <<= 2;
|
||||
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write32(bmp_address,
|
||||
makeacol32((*addr) & 0xff,
|
||||
(*addr) & 0xff,
|
||||
(*addr) & 0xff, 255));
|
||||
addr++;
|
||||
bmp_address += 4;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
bmp_unwrite_line(bmp);
|
||||
}
|
||||
|
||||
template<>
|
||||
void ImageImpl<IndexedTraits>::to_allegro(BITMAP *bmp, int _x, int _y) const
|
||||
{
|
||||
#define RGB_TRIPLET \
|
||||
_rgb_scale_6[_current_palette[_index_cmap[(*addr)]].r], \
|
||||
_rgb_scale_6[_current_palette[_index_cmap[(*addr)]].g], \
|
||||
_rgb_scale_6[_current_palette[_index_cmap[(*addr)]].b]
|
||||
|
||||
const_address_t addr = raw_pixels();
|
||||
unsigned long bmp_address;
|
||||
int depth = bitmap_color_depth(bmp);
|
||||
int x, y;
|
||||
|
||||
bmp_select(bmp);
|
||||
|
||||
switch (depth) {
|
||||
|
||||
case 8:
|
||||
#if defined GFX_MODEX && !defined ALLEGRO_UNIX
|
||||
if (is_planar_bitmap (bmp)) {
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = (unsigned long)bmp->line[_y];
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
outportw(0x3C4, (0x100<<((_x+x)&3))|2);
|
||||
bmp_write8(bmp_address+((_x+x)>>2), _index_cmap[(*addr)]);
|
||||
address++;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write8(bmp_address, _index_cmap[(*addr)]);
|
||||
addr++;
|
||||
bmp_address++;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
#if defined GFX_MODEX && !defined ALLEGRO_UNIX
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 15:
|
||||
_x <<= 1;
|
||||
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write15(bmp_address, makecol15(RGB_TRIPLET));
|
||||
addr++;
|
||||
bmp_address += 2;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 16:
|
||||
_x <<= 1;
|
||||
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write16(bmp_address, makecol16(RGB_TRIPLET));
|
||||
addr++;
|
||||
bmp_address += 2;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 24:
|
||||
_x *= 3;
|
||||
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write24(bmp_address, makecol24(RGB_TRIPLET));
|
||||
addr++;
|
||||
bmp_address += 3;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 32:
|
||||
_x <<= 2;
|
||||
|
||||
for (y=0; y<h; y++) {
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write32(bmp_address, makeacol32(RGB_TRIPLET, 255));
|
||||
addr++;
|
||||
bmp_address += 4;
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
bmp_unwrite_line(bmp);
|
||||
}
|
||||
|
||||
template<>
|
||||
void ImageImpl<BitmapTraits>::to_allegro(BITMAP *bmp, int _x, int _y) const
|
||||
{
|
||||
const_address_t addr;
|
||||
unsigned long bmp_address;
|
||||
int depth = bitmap_color_depth(bmp);
|
||||
div_t d, beg_d = div(0, 8);
|
||||
int color[2];
|
||||
int x, y;
|
||||
|
||||
bmp_select(bmp);
|
||||
|
||||
switch (depth) {
|
||||
|
||||
case 8:
|
||||
color[0] = makecol8(0, 0, 0);
|
||||
color[1] = makecol8(255, 255, 255);
|
||||
|
||||
#if defined GFX_MODEX && !defined ALLEGRO_UNIX
|
||||
if (is_planar_bitmap(bmp)) {
|
||||
for (y=0; y<h; y++) {
|
||||
addr = line_address(y);
|
||||
bmp_address = (unsigned long)bmp->line[_y];
|
||||
|
||||
d = beg_d;
|
||||
for (x=0; x<w; x++) {
|
||||
outportw (0x3C4, (0x100<<((_x+x)&3))|2);
|
||||
bmp_write8(bmp_addr+((_x+x)>>2),
|
||||
color[((*addr) & (1<<d.rem))? 1: 0]);
|
||||
_image_bitmap_next_bit(d, addr);
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
for (y=0; y<h; y++) {
|
||||
addr = line_address(y);
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
d = beg_d;
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write8 (bmp_address++, color[((*addr) & (1<<d.rem))? 1: 0]);
|
||||
_image_bitmap_next_bit(d, addr);
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
#if defined GFX_MODEX && !defined ALLEGRO_UNIX
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 15:
|
||||
color[0] = makecol15(0, 0, 0);
|
||||
color[1] = makecol15(255, 255, 255);
|
||||
|
||||
_x <<= 1;
|
||||
|
||||
for (y=0; y<h; y++) {
|
||||
addr = line_address(y);
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
d = beg_d;
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write15(bmp_address, color[((*addr) & (1<<d.rem))? 1: 0]);
|
||||
bmp_address += 2;
|
||||
_image_bitmap_next_bit(d, addr);
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 16:
|
||||
color[0] = makecol16(0, 0, 0);
|
||||
color[1] = makecol16(255, 255, 255);
|
||||
|
||||
_x <<= 1;
|
||||
|
||||
for (y=0; y<h; y++) {
|
||||
addr = line_address(y);
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
d = beg_d;
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write16(bmp_address, color[((*addr) & (1<<d.rem))? 1: 0]);
|
||||
bmp_address += 2;
|
||||
_image_bitmap_next_bit(d, addr);
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 24:
|
||||
color[0] = makecol24 (0, 0, 0);
|
||||
color[1] = makecol24 (255, 255, 255);
|
||||
|
||||
_x *= 3;
|
||||
|
||||
for (y=0; y<h; y++) {
|
||||
addr = line_address(y);
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
d = beg_d;
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write24(bmp_address, color[((*addr) & (1<<d.rem))? 1: 0]);
|
||||
bmp_address += 3;
|
||||
_image_bitmap_next_bit (d, addr);
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 32:
|
||||
color[0] = makeacol32 (0, 0, 0, 255);
|
||||
color[1] = makeacol32 (255, 255, 255, 255);
|
||||
|
||||
_x <<= 2;
|
||||
|
||||
for (y=0; y<h; y++) {
|
||||
addr = line_address(y);
|
||||
bmp_address = bmp_write_line(bmp, _y)+_x;
|
||||
|
||||
d = beg_d;
|
||||
for (x=0; x<w; x++) {
|
||||
bmp_write32(bmp_address, color[((*addr) & (1<<d.rem))? 1: 0]);
|
||||
bmp_address += 4;
|
||||
_image_bitmap_next_bit(d, addr);
|
||||
}
|
||||
|
||||
_y++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
bmp_unwrite_line(bmp);
|
||||
}
|
||||
|
||||
#endif // RASTER_IMAGE_IMPL_H
|
||||
|
@ -27,27 +27,241 @@
|
||||
|
||||
#include "modules/palettes.h"
|
||||
#include "modules/tools.h"
|
||||
#include "raster/image.h"
|
||||
#include "raster/image_impl.h"
|
||||
#include "raster/raster.h"
|
||||
|
||||
/************************************************************************/
|
||||
/* Render engine */
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// zoomed merge
|
||||
|
||||
template<class Traits>
|
||||
class BlenderHelper
|
||||
{
|
||||
BLEND_COLOR m_blend_color;
|
||||
public:
|
||||
BlenderHelper(int blend_mode)
|
||||
{
|
||||
m_blend_color = Traits::get_blender(blend_mode);
|
||||
}
|
||||
|
||||
inline void operator()(typename Traits::address_t& scanline_address,
|
||||
typename Traits::address_t& dst_address,
|
||||
typename Traits::address_t& src_address,
|
||||
int& opacity)
|
||||
{
|
||||
*scanline_address = (*m_blend_color)(*dst_address, *src_address, opacity);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
class BlenderHelper<IndexedTraits>
|
||||
{
|
||||
int m_blend_mode;
|
||||
public:
|
||||
BlenderHelper(int blend_mode)
|
||||
{
|
||||
m_blend_mode = blend_mode;
|
||||
}
|
||||
|
||||
inline void operator()(IndexedTraits::address_t& scanline_address,
|
||||
IndexedTraits::address_t& dst_address,
|
||||
IndexedTraits::address_t& src_address,
|
||||
int& opacity)
|
||||
{
|
||||
if (m_blend_mode == BLEND_MODE_COPY) {
|
||||
*scanline_address = *src_address;
|
||||
}
|
||||
else {
|
||||
if (*src_address) {
|
||||
if (color_map)
|
||||
*scanline_address = color_map->data[*src_address][*dst_address];
|
||||
else
|
||||
*scanline_address = *src_address;
|
||||
}
|
||||
else
|
||||
*scanline_address = *dst_address;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<class Traits>
|
||||
static void merge_zoomed_image(Image *dst, Image *src,
|
||||
int x, int y, int opacity,
|
||||
int blend_mode, int zoom)
|
||||
{
|
||||
BlenderHelper<Traits> blender(blend_mode);
|
||||
Traits::address_t src_address;
|
||||
Traits::address_t dst_address, dst_address_end;
|
||||
Traits::address_t scanline, scanline_address;
|
||||
int src_x, src_y, src_w, src_h;
|
||||
int dst_x, dst_y, dst_w, dst_h;
|
||||
int box_x, box_y, box_w, box_h;
|
||||
int offsetx, offsety;
|
||||
int line_h, bottom;
|
||||
|
||||
box_w = 1<<zoom;
|
||||
box_h = 1<<zoom;
|
||||
|
||||
src_x = 0;
|
||||
src_y = 0;
|
||||
src_w = src->w;
|
||||
src_h = src->h;
|
||||
|
||||
dst_x = x;
|
||||
dst_y = y;
|
||||
dst_w = src->w<<zoom;
|
||||
dst_h = src->h<<zoom;
|
||||
|
||||
// clipping...
|
||||
if (dst_x < 0) {
|
||||
src_x += (-dst_x)>>zoom;
|
||||
src_w -= (-dst_x)>>zoom;
|
||||
dst_w -= (-dst_x);
|
||||
offsetx = box_w - ((-dst_x) % box_w);
|
||||
dst_x = 0;
|
||||
}
|
||||
else
|
||||
offsetx = 0;
|
||||
|
||||
if (dst_y < 0) {
|
||||
src_y += (-dst_y)>>zoom;
|
||||
src_h -= (-dst_y)>>zoom;
|
||||
dst_h -= (-dst_y);
|
||||
offsety = box_h - ((-dst_y) % box_h);
|
||||
dst_y = 0;
|
||||
}
|
||||
else
|
||||
offsety = 0;
|
||||
|
||||
if (dst_x+dst_w > dst->w) {
|
||||
src_w -= (dst_x+dst_w-dst->w) >> zoom;
|
||||
dst_w = dst->w - dst_x;
|
||||
}
|
||||
|
||||
if (dst_y+dst_h > dst->h) {
|
||||
src_h -= (dst_y+dst_h-dst->h) >> zoom;
|
||||
dst_h = dst->h - dst_y;
|
||||
}
|
||||
|
||||
if ((src_w <= 0) || (src_h <= 0) || (dst_w <= 0) || (dst_h <= 0))
|
||||
return;
|
||||
|
||||
bottom = dst_y+dst_h-1;
|
||||
|
||||
// the scanline variable is used to
|
||||
scanline = new Traits::pixel_t[src_w];
|
||||
|
||||
// for each line to draw of the source image...
|
||||
for (y=0; y<src_h; y++) {
|
||||
assert(src_x >= 0 && src_x < src->w);
|
||||
assert(dst_x >= 0 && dst_x < dst->w);
|
||||
|
||||
// get addresses to each line (beginning of 'src', 'dst', etc.)
|
||||
src_address = ((ImageImpl<Traits>*)src)->line_address(src_y) + src_x;
|
||||
dst_address = ((ImageImpl<Traits>*)dst)->line_address(dst_y) + dst_x;
|
||||
dst_address_end = dst_address + dst_w;
|
||||
scanline_address = scanline;
|
||||
|
||||
// read 'src' and 'dst' and blend them, put the result in `scanline'
|
||||
for (x=0; x<src_w; x++) {
|
||||
assert(scanline_address >= scanline);
|
||||
assert(scanline_address < scanline + src_w);
|
||||
assert(src_address >= ((ImageImpl<Traits>*)src)->line_address(src_y) + src_x);
|
||||
assert(src_address < ((ImageImpl<Traits>*)src)->line_address(src_y) + src_x + src_w);
|
||||
assert(dst_address >= ((ImageImpl<Traits>*)dst)->line_address(dst_y) + dst_x);
|
||||
assert(dst_address < ((ImageImpl<Traits>*)dst)->line_address(dst_y) + dst_x + dst_w);
|
||||
assert(dst_address < dst_address_end);
|
||||
|
||||
blender(scanline_address, dst_address, src_address, opacity);
|
||||
|
||||
src_address++;
|
||||
if (x == 0 && offsetx > 0)
|
||||
dst_address += offsetx;
|
||||
else
|
||||
dst_address += box_w;
|
||||
scanline_address++;
|
||||
|
||||
if (dst_address >= dst_address_end)
|
||||
break;
|
||||
}
|
||||
|
||||
// get the 'height' of the line to be painted in 'dst'
|
||||
if ((offsety > 0) && (y == 0))
|
||||
line_h = offsety;
|
||||
else
|
||||
line_h = box_h;
|
||||
|
||||
// draw the line in `dst'
|
||||
for (box_y=0; box_y<line_h; box_y++) {
|
||||
dst_address = ((ImageImpl<Traits>*)dst)->line_address(dst_y) + dst_x;
|
||||
dst_address_end = dst_address + dst_w;
|
||||
scanline_address = scanline;
|
||||
|
||||
x = 0;
|
||||
|
||||
// first pixel
|
||||
if (offsetx > 0) {
|
||||
for (box_x=0; box_x<offsetx; box_x++) {
|
||||
assert(scanline_address >= scanline);
|
||||
assert(scanline_address < scanline + src_w);
|
||||
assert(dst_address >= ((ImageImpl<Traits>*)dst)->line_address(dst_y) + dst_x);
|
||||
assert(dst_address < ((ImageImpl<Traits>*)dst)->line_address(dst_y) + dst_x + dst_w);
|
||||
assert(dst_address < dst_address_end);
|
||||
|
||||
(*dst_address++) = (*scanline_address);
|
||||
|
||||
if (dst_address >= dst_address_end)
|
||||
goto done_with_line;
|
||||
}
|
||||
|
||||
scanline_address++;
|
||||
x++;
|
||||
}
|
||||
|
||||
// the rest of the line
|
||||
for (; x<src_w; x++) {
|
||||
for (box_x=0; box_x<box_w; box_x++) {
|
||||
assert(dst_address >= ((ImageImpl<Traits>*)dst)->line_address(dst_y) + dst_x);
|
||||
assert(dst_address < ((ImageImpl<Traits>*)dst)->line_address(dst_y) + dst_x + dst_w);
|
||||
|
||||
(*dst_address++) = (*scanline_address);
|
||||
|
||||
if (dst_address >= dst_address_end)
|
||||
goto done_with_line;
|
||||
}
|
||||
|
||||
scanline_address++;
|
||||
}
|
||||
|
||||
done_with_line:;
|
||||
|
||||
if (++dst_y > bottom)
|
||||
goto done_with_blit;
|
||||
}
|
||||
|
||||
// go to the next line in the source image
|
||||
src_y++;
|
||||
}
|
||||
|
||||
done_with_blit:;
|
||||
delete[] scanline;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Render engine
|
||||
|
||||
static int global_opacity = 255;
|
||||
|
||||
static Layer *selected_layer = NULL;
|
||||
static Image *rastering_image = NULL;
|
||||
|
||||
static void render_layer(Sprite *sprite, Layer *layer, Image *image,
|
||||
static void render_layer(Sprite* sprite, Layer* layer, Image* image,
|
||||
int source_x, int source_y,
|
||||
int frame, int zoom,
|
||||
void (*zoomed_func)(Image *, Image *, int, int, int, int, int),
|
||||
void (*zoomed_func)(Image*, Image*, int, int, int, int, int),
|
||||
bool render_background,
|
||||
bool render_transparent);
|
||||
|
||||
static void merge_zoomed_image8(Image *dst, Image *src, int x, int y, int opacity, int blend_mode, int zoom);
|
||||
static void merge_zoomed_image16(Image *dst, Image *src, int x, int y, int opacity, int blend_mode, int zoom);
|
||||
static void merge_zoomed_image32(Image *dst, Image *src, int x, int y, int opacity, int blend_mode, int zoom);
|
||||
|
||||
void set_preview_image(Layer *layer, Image *image)
|
||||
{
|
||||
selected_layer = layer;
|
||||
@ -76,17 +290,17 @@ Image *render_sprite(Sprite *sprite,
|
||||
|
||||
case IMAGE_RGB:
|
||||
depth = 32;
|
||||
zoomed_func = merge_zoomed_image32;
|
||||
zoomed_func = merge_zoomed_image<RgbTraits>;
|
||||
break;
|
||||
|
||||
case IMAGE_GRAYSCALE:
|
||||
depth = 8;
|
||||
zoomed_func = merge_zoomed_image16;
|
||||
zoomed_func = merge_zoomed_image<GrayscaleTraits>;
|
||||
break;
|
||||
|
||||
case IMAGE_INDEXED:
|
||||
depth = 8;
|
||||
zoomed_func = merge_zoomed_image8;
|
||||
zoomed_func = merge_zoomed_image<IndexedTraits>;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -259,439 +473,3 @@ static void render_layer(Sprite *sprite, Layer *layer, Image *image,
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void merge_zoomed_image8(Image *dst, Image *src,
|
||||
int x, int y, int opacity,
|
||||
int blend_mode, int zoom)
|
||||
{
|
||||
ase_uint8 *src_address;
|
||||
ase_uint8 *dst_address;
|
||||
ase_uint8 *scanline, *scanline_address;
|
||||
int src_x, src_y, src_w, src_h;
|
||||
int dst_x, dst_y, dst_w, dst_h;
|
||||
int box_x, box_y, box_w, box_h;
|
||||
int sizeof_box, offsetx, offsety;
|
||||
int line_x, line_h, right, bottom;
|
||||
|
||||
box_w = 1<<zoom;
|
||||
box_h = 1<<zoom;
|
||||
|
||||
src_x = 0;
|
||||
src_y = 0;
|
||||
src_w = src->w;
|
||||
src_h = src->h;
|
||||
|
||||
dst_x = x;
|
||||
dst_y = y;
|
||||
dst_w = src->w<<zoom;
|
||||
dst_h = src->h<<zoom;
|
||||
|
||||
if (dst_x < 0) {
|
||||
src_x += (-dst_x)>>zoom;
|
||||
src_w -= (-dst_x)>>zoom;
|
||||
dst_w -= (-dst_x);
|
||||
offsetx = box_w - ((-dst_x) % box_w);
|
||||
dst_x = 0;
|
||||
}
|
||||
else
|
||||
offsetx = 0;
|
||||
|
||||
if (dst_y < 0) {
|
||||
src_y += (-dst_y)>>zoom;
|
||||
src_h -= (-dst_y)>>zoom;
|
||||
dst_h -= (-dst_y);
|
||||
offsety = box_h - ((-dst_y) % box_h);
|
||||
dst_y = 0;
|
||||
}
|
||||
else
|
||||
offsety = 0;
|
||||
|
||||
if (dst_x+dst_w > dst->w) {
|
||||
src_w -= (dst_x+dst_w-dst->w) >> zoom;
|
||||
dst_w = dst->w - dst_x;
|
||||
}
|
||||
|
||||
if (dst_y+dst_h > dst->h) {
|
||||
src_h -= (dst_y+dst_h-dst->h) >> zoom;
|
||||
dst_h = dst->h - dst_y;
|
||||
}
|
||||
|
||||
if ((src_w <= 0) || (src_h <= 0) || (dst_w <= 0) || (dst_h <= 0))
|
||||
return;
|
||||
|
||||
sizeof_box = sizeof(ase_uint8) * box_w;
|
||||
right = dst_x+dst_w-1;
|
||||
bottom = dst_y+dst_h-1;
|
||||
|
||||
scanline = (ase_uint8*)jmalloc(sizeof(ase_uint8) * src_w);
|
||||
|
||||
/* merge process */
|
||||
|
||||
for (y=0; y<src_h; y++) {
|
||||
/* process a new line */
|
||||
src_address = ((ase_uint8 **)src->line)[src_y] + src_x;
|
||||
dst_address = ((ase_uint8 **)dst->line)[dst_y] + dst_x;
|
||||
scanline_address = scanline;
|
||||
|
||||
/* read `src' and `dst' and blend them, put the result in `scanline' */
|
||||
for (x=0; x<src_w; x++) {
|
||||
if (blend_mode == BLEND_MODE_COPY) {
|
||||
*scanline_address = *src_address;
|
||||
}
|
||||
else {
|
||||
if (*src_address) {
|
||||
if (color_map)
|
||||
*scanline_address = color_map->data[*src_address][*dst_address];
|
||||
else
|
||||
*scanline_address = *src_address;
|
||||
}
|
||||
else
|
||||
*scanline_address = *dst_address;
|
||||
}
|
||||
|
||||
src_address++;
|
||||
dst_address += box_w;
|
||||
scanline_address++;
|
||||
}
|
||||
|
||||
/* get the `height' of the line */
|
||||
if ((offsety > 0) && (y == 0))
|
||||
line_h = offsety;
|
||||
else
|
||||
line_h = box_h;
|
||||
|
||||
/* put the line in `dst' */
|
||||
for (box_y=0; box_y<line_h; box_y++) {
|
||||
dst_address = ((ase_uint8 **)dst->line)[dst_y] + dst_x;
|
||||
scanline_address = scanline;
|
||||
|
||||
line_x = dst_x;
|
||||
x = 0;
|
||||
|
||||
/* first pixel */
|
||||
if (offsetx > 0) {
|
||||
for (box_x=0; box_x<offsetx; box_x++) {
|
||||
(*dst_address++) = (*scanline_address);
|
||||
|
||||
line_x++;
|
||||
if (line_x > right)
|
||||
goto done_with_line;
|
||||
}
|
||||
|
||||
scanline_address++;
|
||||
x++;
|
||||
}
|
||||
|
||||
/* the rest of the line */
|
||||
for (; x<src_w; x++) {
|
||||
for (box_x=0; box_x<box_w; box_x++) {
|
||||
(*dst_address++) = (*scanline_address);
|
||||
|
||||
line_x++;
|
||||
if (line_x > right)
|
||||
goto done_with_line;
|
||||
}
|
||||
|
||||
scanline_address++;
|
||||
}
|
||||
|
||||
done_with_line:;
|
||||
|
||||
dst_y++;
|
||||
if (dst_y > bottom)
|
||||
goto done_with_blit;
|
||||
}
|
||||
|
||||
/* go to the next line */
|
||||
src_y++;
|
||||
}
|
||||
|
||||
done_with_blit:;
|
||||
jfree(scanline);
|
||||
}
|
||||
|
||||
static void merge_zoomed_image16(Image *dst, Image *src,
|
||||
int x, int y, int opacity,
|
||||
int blend_mode, int zoom)
|
||||
{
|
||||
BLEND_COLOR blender;
|
||||
ase_uint16 *src_address;
|
||||
ase_uint16 *dst_address;
|
||||
ase_uint16 *scanline, *scanline_address;
|
||||
int src_x, src_y, src_w, src_h;
|
||||
int dst_x, dst_y, dst_w, dst_h;
|
||||
int box_x, box_y, box_w, box_h;
|
||||
int sizeof_box, offsetx, offsety;
|
||||
int line_x, line_h, right, bottom;
|
||||
|
||||
blender = GrayscaleTraits::get_blender(blend_mode);
|
||||
|
||||
box_w = 1<<zoom;
|
||||
box_h = 1<<zoom;
|
||||
|
||||
src_x = 0;
|
||||
src_y = 0;
|
||||
src_w = src->w;
|
||||
src_h = src->h;
|
||||
|
||||
dst_x = x;
|
||||
dst_y = y;
|
||||
dst_w = src->w<<zoom;
|
||||
dst_h = src->h<<zoom;
|
||||
|
||||
if (dst_x < 0) {
|
||||
src_x += (-dst_x)>>zoom;
|
||||
src_w -= (-dst_x)>>zoom;
|
||||
dst_w -= (-dst_x);
|
||||
offsetx = box_w - ((-dst_x) % box_w);
|
||||
dst_x = 0;
|
||||
}
|
||||
else
|
||||
offsetx = 0;
|
||||
|
||||
if (dst_y < 0) {
|
||||
src_y += (-dst_y)>>zoom;
|
||||
src_h -= (-dst_y)>>zoom;
|
||||
dst_h -= (-dst_y);
|
||||
offsety = box_h - ((-dst_y) % box_h);
|
||||
dst_y = 0;
|
||||
}
|
||||
else
|
||||
offsety = 0;
|
||||
|
||||
if (dst_x+dst_w > dst->w) {
|
||||
src_w -= (dst_x+dst_w-dst->w) >> zoom;
|
||||
dst_w = dst->w - dst_x;
|
||||
}
|
||||
|
||||
if (dst_y+dst_h > dst->h) {
|
||||
src_h -= (dst_y+dst_h-dst->h) >> zoom;
|
||||
dst_h = dst->h - dst_y;
|
||||
}
|
||||
|
||||
if ((src_w <= 0) || (src_h <= 0) || (dst_w <= 0) || (dst_h <= 0))
|
||||
return;
|
||||
|
||||
sizeof_box = sizeof(ase_uint16) * box_w;
|
||||
right = dst_x+dst_w-1;
|
||||
bottom = dst_y+dst_h-1;
|
||||
|
||||
scanline = (ase_uint16*)jmalloc(sizeof(ase_uint16) * src_w);
|
||||
|
||||
/* merge process */
|
||||
|
||||
/* opacity = (opacity)? opacity+1: 0; */
|
||||
|
||||
for (y=0; y<src_h; y++) {
|
||||
/* process a new line */
|
||||
src_address = ((ase_uint16 **)src->line)[src_y] + src_x;
|
||||
dst_address = ((ase_uint16 **)dst->line)[dst_y] + dst_x;
|
||||
scanline_address = scanline;
|
||||
|
||||
/* read `src' and `dst' and blend them, put the result in `scanline' */
|
||||
for (x=0; x<src_w; x++) {
|
||||
*scanline_address = (*blender)(*dst_address, *src_address, opacity);
|
||||
|
||||
src_address++;
|
||||
dst_address += box_w;
|
||||
scanline_address++;
|
||||
}
|
||||
|
||||
/* get the `height' of the line */
|
||||
if ((offsety > 0) && (y == 0))
|
||||
line_h = offsety;
|
||||
else
|
||||
line_h = box_h;
|
||||
|
||||
/* put the line in `dst' */
|
||||
for (box_y=0; box_y<line_h; box_y++) {
|
||||
dst_address = ((ase_uint16 **)dst->line)[dst_y] + dst_x;
|
||||
scanline_address = scanline;
|
||||
|
||||
line_x = dst_x;
|
||||
x = 0;
|
||||
|
||||
/* first pixel */
|
||||
if (offsetx > 0) {
|
||||
for (box_x=0; box_x<offsetx; box_x++) {
|
||||
(*dst_address++) = (*scanline_address);
|
||||
|
||||
line_x++;
|
||||
if (line_x > right)
|
||||
goto done_with_line;
|
||||
}
|
||||
|
||||
scanline_address++;
|
||||
x++;
|
||||
}
|
||||
|
||||
/* the rest of the line */
|
||||
for (; x<src_w; x++) {
|
||||
for (box_x=0; box_x<box_w; box_x++) {
|
||||
(*dst_address++) = (*scanline_address);
|
||||
|
||||
line_x++;
|
||||
if (line_x > right)
|
||||
goto done_with_line;
|
||||
}
|
||||
|
||||
scanline_address++;
|
||||
}
|
||||
|
||||
done_with_line:;
|
||||
|
||||
dst_y++;
|
||||
if (dst_y > bottom)
|
||||
goto done_with_blit;
|
||||
}
|
||||
|
||||
/* go to the next line */
|
||||
src_y++;
|
||||
}
|
||||
|
||||
done_with_blit:;
|
||||
jfree(scanline);
|
||||
}
|
||||
|
||||
static void merge_zoomed_image32(Image *dst, Image *src,
|
||||
int x, int y, int opacity,
|
||||
int blend_mode, int zoom)
|
||||
{
|
||||
BLEND_COLOR blender;
|
||||
ase_uint32 *src_address;
|
||||
ase_uint32 *dst_address;
|
||||
ase_uint32 *scanline, *scanline_address;
|
||||
int src_x, src_y, src_w, src_h;
|
||||
int dst_x, dst_y, dst_w, dst_h;
|
||||
int box_x, box_y, box_w, box_h;
|
||||
int sizeof_box, offsetx, offsety;
|
||||
int line_x, line_h, right, bottom;
|
||||
|
||||
blender = RgbTraits::get_blender(blend_mode);
|
||||
|
||||
box_w = 1<<zoom;
|
||||
box_h = 1<<zoom;
|
||||
|
||||
src_x = 0;
|
||||
src_y = 0;
|
||||
src_w = src->w;
|
||||
src_h = src->h;
|
||||
|
||||
dst_x = x;
|
||||
dst_y = y;
|
||||
dst_w = src->w<<zoom;
|
||||
dst_h = src->h<<zoom;
|
||||
|
||||
if (dst_x < 0) {
|
||||
src_x += (-dst_x)>>zoom;
|
||||
src_w -= (-dst_x)>>zoom;
|
||||
dst_w -= (-dst_x);
|
||||
offsetx = box_w - ((-dst_x) % box_w);
|
||||
dst_x = 0;
|
||||
}
|
||||
else
|
||||
offsetx = 0;
|
||||
|
||||
if (dst_y < 0) {
|
||||
src_y += (-dst_y)>>zoom;
|
||||
src_h -= (-dst_y)>>zoom;
|
||||
dst_h -= (-dst_y);
|
||||
offsety = box_h - ((-dst_y) % box_h);
|
||||
dst_y = 0;
|
||||
}
|
||||
else
|
||||
offsety = 0;
|
||||
|
||||
if (dst_x+dst_w > dst->w) {
|
||||
src_w -= (dst_x+dst_w-dst->w) >> zoom;
|
||||
dst_w = dst->w - dst_x;
|
||||
}
|
||||
|
||||
if (dst_y+dst_h > dst->h) {
|
||||
src_h -= (dst_y+dst_h-dst->h) >> zoom;
|
||||
dst_h = dst->h - dst_y;
|
||||
}
|
||||
|
||||
if ((src_w <= 0) || (src_h <= 0) || (dst_w <= 0) || (dst_h <= 0))
|
||||
return;
|
||||
|
||||
sizeof_box = sizeof(ase_uint32) * box_w;
|
||||
right = dst_x+dst_w-1;
|
||||
bottom = dst_y+dst_h-1;
|
||||
|
||||
scanline = (ase_uint32*)jmalloc(sizeof(ase_uint32) * src_w);
|
||||
|
||||
/* merge process */
|
||||
|
||||
/* opacity = (opacity)? opacity+1: 0; */
|
||||
|
||||
for (y=0; y<src_h; y++) {
|
||||
/* process a new line */
|
||||
src_address = ((ase_uint32 **)src->line)[src_y] + src_x;
|
||||
dst_address = ((ase_uint32 **)dst->line)[dst_y] + dst_x;
|
||||
scanline_address = scanline;
|
||||
|
||||
/* read `src' and `dst' and blend them, put the result in `scanline' */
|
||||
for (x=0; x<src_w; x++) {
|
||||
*scanline_address = (*blender)(*dst_address, *src_address, opacity);
|
||||
|
||||
src_address++;
|
||||
dst_address += box_w;
|
||||
scanline_address++;
|
||||
}
|
||||
|
||||
/* get the `height' of the line */
|
||||
if ((offsety > 0) && (y == 0))
|
||||
line_h = offsety;
|
||||
else
|
||||
line_h = box_h;
|
||||
|
||||
/* put the line in `dst' */
|
||||
for (box_y=0; box_y<line_h; box_y++) {
|
||||
dst_address = ((ase_uint32 **)dst->line)[dst_y] + dst_x;
|
||||
scanline_address = scanline;
|
||||
|
||||
line_x = dst_x;
|
||||
x = 0;
|
||||
|
||||
/* first pixel */
|
||||
if (offsetx > 0) {
|
||||
for (box_x=0; box_x<offsetx; box_x++) {
|
||||
(*dst_address++) = (*scanline_address);
|
||||
|
||||
line_x++;
|
||||
if (line_x > right)
|
||||
goto done_with_line;
|
||||
}
|
||||
|
||||
scanline_address++;
|
||||
x++;
|
||||
}
|
||||
|
||||
/* the rest of the line */
|
||||
for (; x<src_w; x++) {
|
||||
for (box_x=0; box_x<box_w; box_x++) {
|
||||
(*dst_address++) = (*scanline_address);
|
||||
|
||||
line_x++;
|
||||
if (line_x > right)
|
||||
goto done_with_line;
|
||||
}
|
||||
|
||||
scanline_address++;
|
||||
}
|
||||
|
||||
done_with_line:;
|
||||
|
||||
dst_y++;
|
||||
if (dst_y > bottom)
|
||||
goto done_with_blit;
|
||||
}
|
||||
|
||||
/* go to the next line */
|
||||
src_y++;
|
||||
}
|
||||
|
||||
done_with_blit:;
|
||||
jfree(scanline);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user