- Now "Image" is a C++ class with virtual methods;

- Removed ImageMethods (the C vtable for old "Image" structure);
- Added ImageImpl and ImageTraits;
- Added "Sprite Size" command (feature #2671468);
- Added "Canvas Size" command;
This commit is contained in:
David Capello 2009-05-31 16:02:32 +00:00
parent 6f9bccd65b
commit dd003a8f33
50 changed files with 2085 additions and 1951 deletions

View File

@ -1,3 +1,18 @@
2009-05-30 David A. Capello <davidcapello@gmail.com>
* src/raster/image_impl.h (ImageImpl): Changed the implementation of
images with templates.
2009-05-20 David A. Capello <davidcapello@gmail.com>
* src/commands/cmd_sprite_size.cpp (cmd_sprite_size_execute): Implemented
feature #2671468: Resize a sprite.
2009-05-17 David A. Capello <davidcapello@gmail.com>
* src/commands/cmd_canvas_size.cpp (cmd_canvas_size_execute):
Added command to change the canvas size.
2009-03-08 David A. Capello <davidcapello@gmail.com> 2009-03-08 David A. Capello <davidcapello@gmail.com>
* src/modules/tools.cpp: Now tiled mode can be specified by X * src/modules/tools.cpp: Now tiled mode can be specified by X

View File

@ -2,11 +2,13 @@
NEWS NEWS
=================================== ===================================
0.6.2 0.7
----- ---
+ Copy & Paste use Windows clipboard (feature #2577954). + Added "Sprite Size" command (feature #2671468).
+ Added "Save Copy As" command (feature #2636076). + Added "Save Copy As" command (feature #2636076).
+ Copy & Paste use Windows clipboard (feature #2577954).
+ Added "Canvas Size" and "Rotate Canvas" commands.
+ Fixed compilation support for gcc 64 bits. + Fixed compilation support for gcc 64 bits.
+ Fixed a bug with multiple editors and paste command. + Fixed a bug with multiple editors and paste command.
+ Fixed a bug in the File Open dialog when user presses ENTER key + Fixed a bug in the File Open dialog when user presses ENTER key

View File

@ -2,7 +2,10 @@ High priority work
------------------ ------------------
- search for TODO; - search for TODO;
- fix this: the sliders in Tools Configuration are too big - Ctrl+X / Ctrl+C / Ctrl+V should Cut/Copy/Paste in jentries.
- fix problems with tiled mode XY in drawing corners (I cannot
reproduce the exact scenario).
- fix sliders in Tools Configuration, they are too big
for small resolutions. for small resolutions.
- rewritten palette-editor to edit multiple-palettes. - rewritten palette-editor to edit multiple-palettes.
- fix quantize (one palette for all frames, one palette per frame) - fix quantize (one palette for all frames, one palette per frame)
@ -16,7 +19,6 @@ High priority work
- when press Plus/Minus pad in the editor and the configuration tool - when press Plus/Minus pad in the editor and the configuration tool
window is active, the slider of the "Brush Size" must be updated. window is active, the slider of the "Brush Size" must be updated.
- add a consistent error handling. - add a consistent error handling.
- drag & drop files in Windows.
- add two DrawClick2: - add two DrawClick2:
- DrawClick2FreeHand - DrawClick2FreeHand
- DrawClick2Shape - DrawClick2Shape
@ -32,10 +34,6 @@ High priority work
- layer movement between sets in animation-editor; - layer movement between sets in animation-editor;
+ add all the "set" stuff again; + add all the "set" stuff again;
- options to change the curve type (in curedit.c); - options to change the curve type (in curedit.c);
- More Commands:
+ resize sprite;
+ rotate sprite (90 CW, CCW, Any Angle);
+ canvas size;
- gaussian blur; - gaussian blur;
- RGB and HSV effects; - RGB and HSV effects;
- color-curve stock; - color-curve stock;

View File

@ -24,7 +24,7 @@
/* general information */ /* general information */
#define PACKAGE "ASE" #define PACKAGE "ASE"
#define VERSION "0.6.2" #define VERSION "0.7"
#define WEBSITE "http://www.aseprite.org/" #define WEBSITE "http://www.aseprite.org/"
#define COPYRIGHT "Copyright (C) 2001-2009 David Capello" #define COPYRIGHT "Copyright (C) 2001-2009 David Capello"

View File

@ -81,7 +81,6 @@
<key tool="paint_bucket" shortcut="G" /> <key tool="paint_bucket" shortcut="G" />
<key tool="line" shortcut="L" /> <key tool="line" shortcut="L" />
<key tool="curve" shortcut="V" /> <key tool="curve" shortcut="V" />
<key tool="curve" shortcut="L" />
<key tool="rectangle" shortcut="U" /> <key tool="rectangle" shortcut="U" />
<key tool="ellipse" shortcut="O" /> <key tool="ellipse" shortcut="O" />
<key tool="ellipse" shortcut="U" /> <key tool="ellipse" shortcut="U" />
@ -127,12 +126,23 @@
</menu> </menu>
<menu name="&Sprite"> <menu name="&Sprite">
<item command="sprite_properties" name="&Properties..." /> <item command="sprite_properties" name="&Properties..." />
<separator /> <item command="change_image_type" name="Color &Mode..." />
<item command="change_image_type" name="&Color Mode..." />
<separator /> <separator />
<item command="duplicate_sprite" name="&Duplicate..." /> <item command="duplicate_sprite" name="&Duplicate..." />
<separator />
<item command="sprite_size" name="&Sprite Size..." />
<item command="canvas_size" name="&Canvas Size..." />
<menu name name="&Rotate Canvas">
<item command="rotate_canvas" name="180" argument="180" />
<item command="rotate_canvas" name="90 CW" argument="90" />
<item command="rotate_canvas" name="90 CCW" argument="-90" />
<separator />
<item command="flip_canvas_horizontal" name="Flip Canvas &Horizontal" />
<item command="flip_canvas_vertical" name="Flip Canvas &Vertical" />
</menu>
<separator />
<item command="crop_sprite" name="Cr&op" /> <item command="crop_sprite" name="Cr&op" />
<item command="autocrop_sprite" name="&Auto Crop" /> <item command="autocrop_sprite" name="&Trim" />
</menu> </menu>
<menu name="&Layer"> <menu name="&Layer">
<item command="layer_properties" name="&Properties..." /> <item command="layer_properties" name="&Properties..." />

34
data/jids/canvas.jid Normal file
View File

@ -0,0 +1,34 @@
<!-- ASE - Allegro Sprite Editor -->
<!-- Copyright (C) 2001-2009 by David Capello -->
<jinete>
<window text="Canvas Size" name="canvas_size">
<box vertical>
<box horizontal>
<box vertical homogeneous>
<label text="Left:" />
<label text="Right:" />
</box>
<box vertical homogeneous>
<entry text="0" name="left" maxsize="32" maxwidth="64" tooltip="Columns to be added/removed in the left side.\nUse a negative number to remove columns." />
<entry text="0" name="right" maxsize="32" maxwidth="64" tooltip="Columns to be added/removed in the right side.\nUse a negative number to remove columns." />
</box>
<box vertical homogeneous>
<label text="Top:" />
<label text="Bottom:" />
</box>
<box vertical homogeneous>
<entry text="0" name="top" maxsize="32" maxwidth="64" tooltip="Rows to be added/removed in the top side.\nUse a negative number to remove rows." />
<entry text="0" name="bottom" maxsize="32" maxwidth="64" tooltip="Rows to be added/removed in the bottom side.\nUse a negative number to remove rows." />
</box>
</box>
<separator horizontal />
<box horizontal>
<box horizontal expansive />
<box horizontal homogeneous>
<button text="&OK" name="ok" magnetic width="60" />
<button text="&Cancel" />
</box>
</box>
</box>
</window>
</jinete>

52
data/jids/sprsize.jid Normal file
View File

@ -0,0 +1,52 @@
<!-- ASE - Allegro Sprite Editor -->
<!-- Copyright (C) 2001-2009 by David Capello -->
<jinete>
<window text="Sprite Size" name="sprite_size">
<box vertical>
<box vertical>
<separator text="Pixels:" left horizontal />
<box vertical expansive>
<box horizontal>
<box vertical homogeneous>
<label text="Width:" />
<label text="Height:" />
</box>
<box vertical homogeneous expansive>
<entry expansive name="width_px" maxsize=8 magnetic tooltip="New width for the sprite (in pixels)" />
<entry expansive name="height_px" maxsize=8 tooltip="New height for the sprite (in pixels)" />
</box>
<check text="Lock Ratio" name="lock_ratio" selected />
</box>
</box>
<separator text="Percentage:" left horizontal />
<box vertical expansive>
<box horizontal>
<box vertical homogeneous>
<label text="Width:" />
<label text="Height:" />
</box>
<box vertical homogeneous expansive>
<entry expansive text="100%%" name="width_perc" maxsize=8 magnetic tooltip="New width for the sprite\nPercentage of current width." />
<entry expansive text="100%%" name="height_perc" maxsize=8 tooltip="New height for the sprite\nPercentage of current height." />
</box>
<box horizontal width="64" />
</box>
</box>
</box>
<separator text="Interpolation:" left horizontal />
<box vertical expansive>
<box horizontal>
<label text="Method:" />
<combobox name="method" expansive />
</box>
</box>
<box horizontal>
<box horizontal expansive />
<box horizontal homogeneous>
<button text="&OK" name="ok" magnetic width="60" />
<button text="&Cancel" />
</box>
</box>
</box>
</window>
</jinete>

View File

@ -5,7 +5,7 @@
\palette ase.pcx \palette ase.pcx
\image ase.pcx \image ase.pcx
Welcome to ASE 0.6.1 Welcome to ASE 0.7
READ THIS! READ THIS!

View File

@ -9,6 +9,7 @@ COMMON_SOURCES = \
src/commands/cmd_about.cpp \ src/commands/cmd_about.cpp \
src/commands/cmd_advanced_mode.cpp \ src/commands/cmd_advanced_mode.cpp \
src/commands/cmd_background_from_layer.cpp \ src/commands/cmd_background_from_layer.cpp \
src/commands/cmd_canvas_size.cpp \
src/commands/cmd_cel_properties.cpp \ src/commands/cmd_cel_properties.cpp \
src/commands/cmd_change_image_type.cpp \ src/commands/cmd_change_image_type.cpp \
src/commands/cmd_clear.cpp \ src/commands/cmd_clear.cpp \
@ -65,6 +66,7 @@ COMMON_SOURCES = \
src/commands/cmd_select_file.cpp \ src/commands/cmd_select_file.cpp \
src/commands/cmd_sprite_editor.cpp \ src/commands/cmd_sprite_editor.cpp \
src/commands/cmd_sprite_properties.cpp \ src/commands/cmd_sprite_properties.cpp \
src/commands/cmd_sprite_size.cpp \
src/commands/cmd_switch_colors.cpp \ src/commands/cmd_switch_colors.cpp \
src/commands/cmd_tips.cpp \ src/commands/cmd_tips.cpp \
src/commands/cmd_undo.cpp \ src/commands/cmd_undo.cpp \

View File

@ -1,7 +1,7 @@
#! /bin/sh #! /bin/sh
dir="`pwd`" dir="`pwd`"
version=0.6.2 version=0.7
distdir=ase-$version distdir=ase-$version
freetype_files="third_party/freetype/ChangeLog \ freetype_files="third_party/freetype/ChangeLog \

View File

@ -0,0 +1,97 @@
/* 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 <allegro/unicode.h>
#include "jinete/jinete.h"
#include "commands/commands.h"
#include "core/app.h"
#include "modules/gui.h"
#include "modules/sprites.h"
#include "raster/image.h"
#include "raster/mask.h"
#include "raster/sprite.h"
#include "raster/undoable.h"
#include "widgets/colbar.h"
static bool cmd_canvas_size_enabled(const char *argument)
{
return current_sprite != NULL;
}
static void cmd_canvas_size_execute(const char *argument)
{
JWidget window, left, top, right, bottom, ok;
Sprite* sprite = current_sprite;
// load the window widget
window = load_widget("canvas.jid", "canvas_size");
if (!window)
return;
if (!get_widgets(window,
"left", &left,
"top", &top,
"right", &right,
"bottom", &bottom,
"ok", &ok, NULL)) {
jwidget_free(window);
return;
}
jwindow_remap(window);
jwindow_center(window);
load_window_pos(window, "CanvasSize");
jwidget_show(window);
jwindow_open_fg(window);
save_window_pos(window, "CanvasSize");
if (jwindow_get_killer(window) == ok) {
int x1 = -left->text_int();
int y1 = -top->text_int();
int x2 = sprite->w + right->text_int();
int y2 = sprite->h + bottom->text_int();
if (x2 <= x1) x2 = x1+1;
if (y2 <= y1) y2 = y1+1;
{
Undoable undoable(sprite, "Canvas Size");
int bgcolor = get_color_for_image(sprite->imgtype,
colorbar_get_bg_color(app_get_colorbar()));
undoable.crop_sprite(x1, y1, x2-x1, y2-y1, bgcolor);
undoable.commit();
}
sprite_generate_mask_boundaries(sprite);
update_screen_for_sprite(sprite);
}
jwidget_free(window);
}
Command cmd_canvas_size = {
CMD_CANVAS_SIZE,
cmd_canvas_size_enabled,
NULL,
cmd_canvas_size_execute,
NULL
};

View File

@ -95,7 +95,7 @@ static void cmd_cel_properties_execute(const char *argument)
/* dimension (and memory size) */ /* dimension (and memory size) */
memsize = memsize =
IMAGE_LINE_SIZE(sprite->stock->image[cel->image], image_line_size(sprite->stock->image[cel->image],
sprite->stock->image[cel->image]->w)* sprite->stock->image[cel->image]->w)*
sprite->stock->image[cel->image]->h; sprite->stock->image[cel->image]->h;

View File

@ -0,0 +1,223 @@
/* 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 <allegro/unicode.h>
#include "jinete/jinete.h"
#include "core/cfg.h"
#include "commands/commands.h"
#include "modules/gui.h"
#include "modules/palettes.h"
#include "modules/sprites.h"
#include "raster/cel.h"
#include "raster/image.h"
#include "raster/sprite.h"
#include "raster/stock.h"
#include "raster/undoable.h"
#define PERC_FORMAT "%.1f%%"
static bool lock_ratio_change_hook(JWidget widget, void *data);
static bool width_px_change_hook(JWidget widget, void *data);
static bool height_px_change_hook(JWidget widget, void *data);
static bool width_perc_change_hook(JWidget widget, void *data);
static bool height_perc_change_hook(JWidget widget, void *data);
static bool cmd_sprite_size_enabled(const char *argument)
{
return current_sprite != NULL;
}
static void cmd_sprite_size_execute(const char *argument)
{
JWidget window, width_px, height_px, width_perc, height_perc, lock_ratio, method, ok;
Sprite* sprite = current_sprite;
// load the window widget
window = load_widget("sprsize.jid", "sprite_size");
if (!window)
return;
if (!get_widgets(window,
"width_px", &width_px,
"height_px", &height_px,
"width_perc", &width_perc,
"height_perc", &height_perc,
"lock_ratio", &lock_ratio,
"method", &method,
"ok", &ok, NULL)) {
jwidget_free(window);
return;
}
width_px->textf("%d", sprite->w);
height_px->textf("%d", sprite->h);
HOOK(lock_ratio, JI_SIGNAL_CHECK_CHANGE, lock_ratio_change_hook, 0);
HOOK(width_px, JI_SIGNAL_ENTRY_CHANGE, width_px_change_hook, 0);
HOOK(height_px, JI_SIGNAL_ENTRY_CHANGE, height_px_change_hook, 0);
HOOK(width_perc, JI_SIGNAL_ENTRY_CHANGE, width_perc_change_hook, 0);
HOOK(height_perc, JI_SIGNAL_ENTRY_CHANGE, height_perc_change_hook, 0);
jcombobox_add_string(method, "Nearest-neighbor", NULL);
jcombobox_add_string(method, "Bilinear", NULL);
jcombobox_select_index(method, get_config_int("SpriteSize", "Method", RESIZE_METHOD_NEAREST_NEIGHBOR));
jwindow_remap(window);
jwindow_center(window);
load_window_pos(window, "SpriteSize");
jwidget_show(window);
jwindow_open_fg(window);
save_window_pos(window, "SpriteSize");
if (jwindow_get_killer(window) == ok) {
int new_width = width_px->text_int();
int new_height = height_px->text_int();
{
Undoable undoable(sprite, "Sprite Size");
ResizeMethod resize_method =
(ResizeMethod)jcombobox_get_selected_index(method);
set_config_int("SpriteSize", "Method", resize_method);
// get all sprite cels
JList cels = jlist_new();
sprite_get_cels(sprite, cels);
// for each cel...
JLink link;
JI_LIST_FOR_EACH(cels, link) {
Cel* cel = (Cel*)link->data;
// change it location
undoable.set_cel_position(cel,
cel->x * new_width / sprite->w,
cel->y * new_height / sprite->h);
}
jlist_free(cels);
// for each stock's image
for (int i=0; i<sprite->stock->nimage; ++i) {
Image* image = stock_get_image(sprite->stock, i);
if (!image)
continue;
// resize the image
int w = image->w * new_width / sprite->w;
int h = image->h * new_height / sprite->h;
Image* new_image = image_new(image->imgtype, MAX(1, w), MAX(1, h));
image_resize(image, new_image,
resize_method,
get_current_palette(),
orig_rgb_map);
undoable.replace_stock_image(i, new_image);
}
// resize sprite
undoable.set_sprite_size(new_width, new_height);
// TODO resize mask
undoable.commit();
}
sprite_generate_mask_boundaries(sprite);
update_screen_for_sprite(sprite);
}
jwidget_free(window);
}
static bool lock_ratio_change_hook(JWidget widget, void *data)
{
if (widget->selected())
width_px_change_hook(widget->find_sibling("width_px"), NULL);
return true;
}
static bool width_px_change_hook(JWidget widget, void *data)
{
int width = widget->text_int();
double perc = 100.0 * width / current_sprite->w;
widget->find_sibling("width_perc")->textf(PERC_FORMAT, perc);
if (widget->find_sibling("lock_ratio")->selected()) {
widget->find_sibling("height_perc")->textf(PERC_FORMAT, perc);
widget->find_sibling("height_px")->textf("%d", current_sprite->h * width / current_sprite->w);
}
return true;
}
static bool height_px_change_hook(JWidget widget, void *data)
{
int height = widget->text_int();
double perc = 100.0 * height / current_sprite->h;
widget->find_sibling("height_perc")->textf(PERC_FORMAT, perc);
if (widget->find_sibling("lock_ratio")->selected()) {
widget->find_sibling("width_perc")->textf(PERC_FORMAT, perc);
widget->find_sibling("width_px")->textf("%d", current_sprite->w * height / current_sprite->h);
}
return true;
}
static bool width_perc_change_hook(JWidget widget, void *data)
{
double width = widget->text_double();
widget->find_sibling("width_px")->textf("%d", (int)(current_sprite->w * width / 100));
if (widget->find_sibling("lock_ratio")->selected()) {
widget->find_sibling("height_px")->textf("%d", (int)(current_sprite->h * width / 100));
widget->find_sibling("height_perc")->text(widget->text());
}
return true;
}
static bool height_perc_change_hook(JWidget widget, void *data)
{
double height = widget->text_double();
widget->find_sibling("height_px")->textf("%d", (int)(current_sprite->h * height / 100));
if (widget->find_sibling("lock_ratio")->selected()) {
widget->find_sibling("width_px")->textf("%d", (int)(current_sprite->w * height / 100));
widget->find_sibling("width_perc")->text(widget->text());
}
return true;
}
Command cmd_sprite_size = {
CMD_SPRITE_SIZE,
cmd_sprite_size_enabled,
NULL,
cmd_sprite_size_execute,
NULL
};

View File

@ -34,6 +34,7 @@ extern Command cmd_autocrop_sprite;
extern Command cmd_background_from_layer; extern Command cmd_background_from_layer;
extern Command cmd_blur_tool; extern Command cmd_blur_tool;
extern Command cmd_brush_tool; extern Command cmd_brush_tool;
extern Command cmd_canvas_size;
extern Command cmd_cel_properties; extern Command cmd_cel_properties;
extern Command cmd_change_image_type; extern Command cmd_change_image_type;
extern Command cmd_clear; extern Command cmd_clear;
@ -114,6 +115,7 @@ extern Command cmd_split_editor_horizontally;
extern Command cmd_split_editor_vertically; extern Command cmd_split_editor_vertically;
extern Command cmd_spray_tool; extern Command cmd_spray_tool;
extern Command cmd_sprite_properties; extern Command cmd_sprite_properties;
extern Command cmd_sprite_size;
extern Command cmd_switch_colors; extern Command cmd_switch_colors;
extern Command cmd_tips; extern Command cmd_tips;
extern Command cmd_undo; extern Command cmd_undo;
@ -126,6 +128,7 @@ static Command *commands[] = {
&cmd_background_from_layer, &cmd_background_from_layer,
&cmd_blur_tool, &cmd_blur_tool,
&cmd_brush_tool, &cmd_brush_tool,
&cmd_canvas_size,
&cmd_cel_properties, &cmd_cel_properties,
&cmd_change_image_type, &cmd_change_image_type,
&cmd_clear, &cmd_clear,
@ -206,6 +209,7 @@ static Command *commands[] = {
&cmd_split_editor_vertically, &cmd_split_editor_vertically,
&cmd_spray_tool, &cmd_spray_tool,
&cmd_sprite_properties, &cmd_sprite_properties,
&cmd_sprite_size,
&cmd_switch_colors, &cmd_switch_colors,
&cmd_tips, &cmd_tips,
&cmd_undo, &cmd_undo,

View File

@ -27,6 +27,7 @@
#define CMD_BACKGROUND_FROM_LAYER "background_from_layer" #define CMD_BACKGROUND_FROM_LAYER "background_from_layer"
#define CMD_BLUR_TOOL "blur_tool" #define CMD_BLUR_TOOL "blur_tool"
#define CMD_BRUSH_TOOL "brush_tool" #define CMD_BRUSH_TOOL "brush_tool"
#define CMD_CANVAS_SIZE "canvas_size"
#define CMD_CEL_PROPERTIES "cel_properties" #define CMD_CEL_PROPERTIES "cel_properties"
#define CMD_CHANGE_IMAGE_TYPE "change_image_type" #define CMD_CHANGE_IMAGE_TYPE "change_image_type"
#define CMD_CLEAR "clear" #define CMD_CLEAR "clear"
@ -107,6 +108,7 @@
#define CMD_SPLIT_EDITOR_VERTICALLY "split_editor_vertically" #define CMD_SPLIT_EDITOR_VERTICALLY "split_editor_vertically"
#define CMD_SPRAY_TOOL "spray_tool" #define CMD_SPRAY_TOOL "spray_tool"
#define CMD_SPRITE_PROPERTIES "sprite_properties" #define CMD_SPRITE_PROPERTIES "sprite_properties"
#define CMD_SPRITE_SIZE "sprite_size"
#define CMD_SWITCH_COLORS "switch_colors" #define CMD_SWITCH_COLORS "switch_colors"
#define CMD_TIPS "tips" #define CMD_TIPS "tips"
#define CMD_UNDO "undo" #define CMD_UNDO "undo"

View File

@ -308,12 +308,12 @@ JList get_convmatr_stock()
return data.matrices; return data.matrices;
} }
#define GET_CONVMATR_DATA(ptr_type, do_job) \ #define GET_CONVMATR_DATA(Traits, do_job) \
div = matrix->div; \ div = matrix->div; \
mdata = matrix->data; \ mdata = matrix->data; \
\ \
GET_MATRIX_DATA \ GET_MATRIX_DATA \
(ptr_type, \ (Traits::pixel_t, \
src, src_address, \ src, src_address, \
matrix->w, matrix->h, \ matrix->w, matrix->h, \
matrix->cx, matrix->cy, \ matrix->cx, matrix->cy, \
@ -325,7 +325,7 @@ JList get_convmatr_stock()
mdata++; \ mdata++; \
); \ ); \
\ \
color = src->method->getpixel(src, x, y); \ color = image_getpixel_fast<Traits>(src, x, y); \
if (div == 0) { \ if (div == 0) { \
*(dst_address++) = color; \ *(dst_address++) = color; \
continue; \ continue; \
@ -364,7 +364,7 @@ void apply_convolution_matrix4(Effect *effect)
r = g = b = a = 0; r = g = b = a = 0;
GET_CONVMATR_DATA GET_CONVMATR_DATA
(ase_uint32, (RgbTraits,
if (_rgba_geta(color) == 0) if (_rgba_geta(color) == 0)
div -= *mdata; div -= *mdata;
else { else {
@ -441,7 +441,7 @@ void apply_convolution_matrix2(Effect *effect)
k = a = 0; k = a = 0;
GET_CONVMATR_DATA GET_CONVMATR_DATA
(ase_uint16, (GrayscaleTraits,
if (_graya_geta(color) == 0) if (_graya_geta(color) == 0)
div -= *mdata; div -= *mdata;
else { else {
@ -503,7 +503,7 @@ void apply_convolution_matrix1(Effect *effect)
r = g = b = index = 0; r = g = b = index = 0;
GET_CONVMATR_DATA GET_CONVMATR_DATA
(ase_uint8, (IndexedTraits,
r += _rgba_getr(pal->color[color]) * (*mdata); r += _rgba_getr(pal->color[color]) * (*mdata);
g += _rgba_getg(pal->color[color]) * (*mdata); g += _rgba_getg(pal->color[color]) * (*mdata);
b += _rgba_getb(pal->color[color]) * (*mdata); b += _rgba_getb(pal->color[color]) * (*mdata);

View File

@ -97,7 +97,7 @@ void apply_median4(Effect *effect)
for (c=0; c<4; c++) for (c=0; c<4; c++)
qsort(data.channel[c], data.ncolors, sizeof(unsigned char), cmp_channel); qsort(data.channel[c], data.ncolors, sizeof(unsigned char), cmp_channel);
color = src->method->getpixel(src, x, y); color = image_getpixel_fast<RgbTraits>(src, x, y);
if (effect->target & TARGET_RED_CHANNEL) if (effect->target & TARGET_RED_CHANNEL)
r = data.channel[0][data.ncolors/2]; r = data.channel[0][data.ncolors/2];
@ -163,7 +163,7 @@ void apply_median2(Effect *effect)
for (c=0; c<2; c++) for (c=0; c<2; c++)
qsort(data.channel[c], data.ncolors, sizeof(unsigned char), cmp_channel); qsort(data.channel[c], data.ncolors, sizeof(unsigned char), cmp_channel);
color = src->method->getpixel(src, x, y); color = image_getpixel_fast<GrayscaleTraits>(src, x, y);
if (effect->target & TARGET_GRAY_CHANNEL) if (effect->target & TARGET_GRAY_CHANNEL)
k = data.channel[0][data.ncolors/2]; k = data.channel[0][data.ncolors/2];
@ -234,7 +234,7 @@ void apply_median1(Effect *effect)
*(dst_address++) = data.channel[0][data.ncolors/2]; *(dst_address++) = data.channel[0][data.ncolors/2];
} }
else { else {
color = src->method->getpixel(src, x, y); color = image_getpixel_fast<IndexedTraits>(src, x, y);
if (effect->target & TARGET_RED_CHANNEL) if (effect->target & TARGET_RED_CHANNEL)
r = data.channel[0][data.ncolors/2]; r = data.channel[0][data.ncolors/2];

View File

@ -778,7 +778,7 @@ static Cel *ase_file_read_cel_chunk(FILE *f, Sprite *sprite, int frame, int imgt
g = fgetc(f); g = fgetc(f);
b = fgetc(f); b = fgetc(f);
a = fgetc(f); a = fgetc(f);
image->method->putpixel(image, x, y, _rgba(r, g, b, a)); image_putpixel_fast<RgbTraits>(image, x, y, _rgba(r, g, b, a));
} }
fop_progress(fop, (float)ftell(f) / (float)header->size); fop_progress(fop, (float)ftell(f) / (float)header->size);
} }
@ -789,7 +789,7 @@ static Cel *ase_file_read_cel_chunk(FILE *f, Sprite *sprite, int frame, int imgt
for (x=0; x<image->w; x++) { for (x=0; x<image->w; x++) {
k = fgetc(f); k = fgetc(f);
a = fgetc(f); a = fgetc(f);
image->method->putpixel(image, x, y, _graya(k, a)); image_putpixel_fast<GrayscaleTraits>(image, x, y, _graya(k, a));
} }
fop_progress(fop, (float)ftell(f) / (float)header->size); fop_progress(fop, (float)ftell(f) / (float)header->size);
} }
@ -798,7 +798,7 @@ static Cel *ase_file_read_cel_chunk(FILE *f, Sprite *sprite, int frame, int imgt
case IMAGE_INDEXED: case IMAGE_INDEXED:
for (y=0; y<image->h; y++) { for (y=0; y<image->h; y++) {
for (x=0; x<image->w; x++) for (x=0; x<image->w; x++)
image->method->putpixel(image, x, y, fgetc(f)); image_putpixel_fast<IndexedTraits>(image, x, y, fgetc(f));
fop_progress(fop, (float)ftell(f) / (float)header->size); fop_progress(fop, (float)ftell(f) / (float)header->size);
} }
@ -869,7 +869,7 @@ static void ase_file_write_cel_chunk(FILE *f, Cel *cel, Layer *layer, Sprite *sp
case IMAGE_RGB: case IMAGE_RGB:
for (y=0; y<image->h; y++) { for (y=0; y<image->h; y++) {
for (x=0; x<image->w; x++) { for (x=0; x<image->w; x++) {
c = image->method->getpixel(image, x, y); c = image_getpixel_fast<RgbTraits>(image, x, y);
fputc(_rgba_getr(c), f); fputc(_rgba_getr(c), f);
fputc(_rgba_getg(c), f); fputc(_rgba_getg(c), f);
fputc(_rgba_getb(c), f); fputc(_rgba_getb(c), f);
@ -881,7 +881,7 @@ static void ase_file_write_cel_chunk(FILE *f, Cel *cel, Layer *layer, Sprite *sp
case IMAGE_GRAYSCALE: case IMAGE_GRAYSCALE:
for (y=0; y<image->h; y++) { for (y=0; y<image->h; y++) {
for (x=0; x<image->w; x++) { for (x=0; x<image->w; x++) {
c = image->method->getpixel(image, x, y); c = image_getpixel_fast<GrayscaleTraits>(image, x, y);
fputc(_graya_getv(c), f); fputc(_graya_getv(c), f);
fputc(_graya_geta(c), f); fputc(_graya_geta(c), f);
} }
@ -891,7 +891,7 @@ static void ase_file_write_cel_chunk(FILE *f, Cel *cel, Layer *layer, Sprite *sp
case IMAGE_INDEXED: case IMAGE_INDEXED:
for (y=0; y<image->h; y++) { for (y=0; y<image->h; y++) {
for (x=0; x<image->w; x++) for (x=0; x<image->w; x++)
fputc(image->method->getpixel(image, x, y), f); fputc(image_getpixel_fast<IndexedTraits>(image, x, y), f);
} }
break; break;
} }

View File

@ -555,7 +555,7 @@ static int read_bitfields_image(FILE *f, Image *image, BITMAPINFOHEADER *infohea
g = gscale ? gscale[g]: g; g = gscale ? gscale[g]: g;
b = bscale ? bscale[b]: b; b = bscale ? bscale[b]: b;
image->method->putpixel(image, j, line, _rgba(r, g, b, 255)); image_putpixel_fast<RgbTraits>(image, j, line, _rgba(r, g, b, 255));
} }
j = (bytes_per_pixel*j) % 4; j = (bytes_per_pixel*j) % 4;
@ -768,12 +768,12 @@ static bool save_BMP(FileOp *fop)
for (j=0; j<image->w; j++) { for (j=0; j<image->w; j++) {
if (bpp == 8) { if (bpp == 8) {
if (image->imgtype == IMAGE_INDEXED) if (image->imgtype == IMAGE_INDEXED)
fputc(image->method->getpixel(image, j, i), f); fputc(image_getpixel_fast<IndexedTraits>(image, j, i), f);
else if (image->imgtype == IMAGE_GRAYSCALE) else if (image->imgtype == IMAGE_GRAYSCALE)
fputc(_graya_getv(image->method->getpixel(image, j, i)), f); fputc(_graya_getv(image_getpixel_fast<GrayscaleTraits>(image, j, i)), f);
} }
else { else {
c = image->method->getpixel(image, j, i); c = image_getpixel_fast<RgbTraits>(image, j, i);
fputc(_rgba_getb(c), f); fputc(_rgba_getb(c), f);
fputc(_rgba_getg(c), f); fputc(_rgba_getg(c), f);
fputc(_rgba_getr(c), f); fputc(_rgba_getr(c), f);

View File

@ -235,23 +235,23 @@ static bool save_PCX(FileOp *fop)
for (x=0; x<image->w*planes; x++) { /* for each pixel... */ for (x=0; x<image->w*planes; x++) { /* for each pixel... */
if (depth == 8) { if (depth == 8) {
if (image->imgtype == IMAGE_INDEXED) if (image->imgtype == IMAGE_INDEXED)
ch = image->method->getpixel(image, x, y); ch = image_getpixel_fast<IndexedTraits>(image, x, y);
else if (image->imgtype == IMAGE_GRAYSCALE) { else if (image->imgtype == IMAGE_GRAYSCALE) {
c = image->method->getpixel(image, x, y); c = image_getpixel_fast<GrayscaleTraits>(image, x, y);
ch = _graya_getv(c); ch = _graya_getv(c);
} }
} }
else { else {
if (x < image->w) { if (x < image->w) {
c = image->method->getpixel(image, x, y); c = image_getpixel_fast<RgbTraits>(image, x, y);
ch = _rgba_getr(c); ch = _rgba_getr(c);
} }
else if (x<image->w*2) { else if (x<image->w*2) {
c = image->method->getpixel(image, x-image->w, y); c = image_getpixel_fast<RgbTraits>(image, x-image->w, y);
ch = _rgba_getg(c); ch = _rgba_getg(c);
} }
else { else {
c = image->method->getpixel(image, x-image->w*2, y); c = image_getpixel_fast<RgbTraits>(image, x-image->w*2, y);
ch = _rgba_getb(c); ch = _rgba_getb(c);
} }
} }

View File

@ -1682,9 +1682,6 @@ static void line_for_spline(int x1, int y1, int x2, int y2, ToolData *data)
\ \
/* with mask */ \ /* with mask */ \
if (data->mask != NULL) { \ if (data->mask != NULL) { \
int (*getpixel)(const Image *, int, int) = \
data->mask->bitmap->method->getpixel; \
\
if ((y < data->mask_y) || (y >= data->mask_y+data->mask->h)) \ if ((y < data->mask_y) || (y >= data->mask_y+data->mask->h)) \
return; \ return; \
\ \
@ -1694,12 +1691,10 @@ static void line_for_spline(int x1, int y1, int x2, int y2, ToolData *data)
if (x2 > data->mask_x+data->mask->w-1) \ if (x2 > data->mask_x+data->mask->w-1) \
x2 = data->mask_x+data->mask->w-1; \ x2 = data->mask_x+data->mask->w-1; \
\ \
if (data->mask->bitmap != NULL) { \ if (Image* bitmap = data->mask->bitmap) { \
addresses_initialize; \ addresses_initialize; \
for (x=x1; x<=x2; ++x) { \ for (x=x1; x<=x2; ++x) { \
if (getpixel(data->mask->bitmap, \ if (bitmap->getpixel(x-data->mask_x, y-data->mask_y)) \
x-data->mask_x, \
y-data->mask_y)) \
processing; \ processing; \
\ \
addresses_increment; \ addresses_increment; \
@ -1714,17 +1709,17 @@ static void line_for_spline(int x1, int y1, int x2, int y2, ToolData *data)
addresses_increment; \ addresses_increment; \
} }
#define DEFINE_INK_PROCESSING_DST(type, processing) \ #define DEFINE_INK_PROCESSING_DST(Traits, processing) \
DEFINE_INK_PROCESSING(register type *dst_address; , \ DEFINE_INK_PROCESSING(register Traits::address_t dst_address; , \
dst_address = ((type **)data->dst_image->line)[y]+x1; , \ dst_address = ((Traits::address_t*)data->dst_image->line)[y]+x1; , \
++dst_address , \ ++dst_address , \
processing) processing)
#define DEFINE_INK_PROCESSING_SRCDST(type, processing) \ #define DEFINE_INK_PROCESSING_SRCDST(Traits, processing) \
DEFINE_INK_PROCESSING(register type *src_address; \ DEFINE_INK_PROCESSING(register Traits::address_t src_address; \
register type *dst_address; , \ register Traits::address_t dst_address; , \
src_address = ((type **)data->src_image->line)[y]+x1; \ src_address = ((Traits::address_t*)data->src_image->line)[y]+x1; \
dst_address = ((type **)data->dst_image->line)[y]+x1; , \ dst_address = ((Traits::address_t*)data->dst_image->line)[y]+x1; , \
++src_address; \ ++src_address; \
++dst_address; , \ ++dst_address; , \
processing) processing)
@ -1738,7 +1733,7 @@ static void ink_hline32_opaque(int x1, int y, int x2, ToolData *data)
int c = data->color; int c = data->color;
DEFINE_INK_PROCESSING_DST DEFINE_INK_PROCESSING_DST
(ase_uint32, (RgbTraits,
*dst_address = c ); *dst_address = c );
} }
@ -1747,7 +1742,7 @@ static void ink_hline16_opaque(int x1, int y, int x2, ToolData *data)
int c = data->color; int c = data->color;
DEFINE_INK_PROCESSING_DST DEFINE_INK_PROCESSING_DST
(ase_uint16, (GrayscaleTraits,
*dst_address = c ); *dst_address = c );
} }
@ -1756,7 +1751,7 @@ static void ink_hline8_opaque(int x1, int y, int x2, ToolData *data)
int c = data->color; int c = data->color;
DEFINE_INK_PROCESSING_DST DEFINE_INK_PROCESSING_DST
(ase_uint8, (IndexedTraits,
*dst_address = c ); *dst_address = c );
/* memset(((ase_uint8 **)data->dst_image->line)[y]+x1, data->color, x2-x1+1); */ /* memset(((ase_uint8 **)data->dst_image->line)[y]+x1, data->color, x2-x1+1); */
@ -1772,7 +1767,7 @@ static void ink_hline32_glass(int x1, int y, int x2, ToolData *data)
int opacity = data->opacity; int opacity = data->opacity;
DEFINE_INK_PROCESSING_SRCDST DEFINE_INK_PROCESSING_SRCDST
(ase_uint32, (RgbTraits,
*dst_address = _rgba_blend_normal(*src_address, color, opacity)); *dst_address = _rgba_blend_normal(*src_address, color, opacity));
} }
@ -1782,7 +1777,7 @@ static void ink_hline16_glass(int x1, int y, int x2, ToolData *data)
int opacity = data->opacity; int opacity = data->opacity;
DEFINE_INK_PROCESSING_SRCDST DEFINE_INK_PROCESSING_SRCDST
(ase_uint16, (GrayscaleTraits,
*dst_address = _graya_blend_normal(*src_address, color, opacity)); *dst_address = _graya_blend_normal(*src_address, color, opacity));
} }
@ -1794,7 +1789,7 @@ static void ink_hline8_glass(int x1, int y, int x2, ToolData *data)
int opacity = data->opacity; int opacity = data->opacity;
DEFINE_INK_PROCESSING_SRCDST DEFINE_INK_PROCESSING_SRCDST
(ase_uint8, (IndexedTraits,
{ {
c = _rgba_blend_normal(pal->color[*src_address], tc, opacity); c = _rgba_blend_normal(pal->color[*src_address], tc, opacity);
*dst_address = orig_rgb_map->data *dst_address = orig_rgb_map->data
@ -1820,7 +1815,7 @@ static void ink_hline32_soften(int x1, int y, int x2, ToolData *data)
ase_uint32 *src_address2; ase_uint32 *src_address2;
DEFINE_INK_PROCESSING_SRCDST DEFINE_INK_PROCESSING_SRCDST
(ase_uint32, (RgbTraits,
{ {
c = 0; c = 0;
r = g = b = a = 0; r = g = b = a = 0;
@ -1870,7 +1865,7 @@ static void ink_hline16_soften(int x1, int y, int x2, ToolData *data)
ase_uint16 *src_address2; ase_uint16 *src_address2;
DEFINE_INK_PROCESSING_SRCDST DEFINE_INK_PROCESSING_SRCDST
(ase_uint16, (GrayscaleTraits,
{ {
c = 0; c = 0;
v = a = 0; v = a = 0;
@ -1915,7 +1910,7 @@ static void ink_hline8_soften(int x1, int y, int x2, ToolData *data)
ase_uint8 *src_address2; ase_uint8 *src_address2;
DEFINE_INK_PROCESSING_SRCDST DEFINE_INK_PROCESSING_SRCDST
(ase_uint8, (IndexedTraits,
{ {
c = 0; c = 0;
r = g = b = a = 0; r = g = b = a = 0;
@ -1963,7 +1958,7 @@ static void ink_hline32_replace(int x1, int y, int x2, ToolData *data)
int opacity = data->opacity; int opacity = data->opacity;
DEFINE_INK_PROCESSING_SRCDST DEFINE_INK_PROCESSING_SRCDST
(ase_uint32, (RgbTraits,
if (*src_address == other_color) { if (*src_address == other_color) {
*dst_address = _rgba_blend_normal(*src_address, color, opacity); *dst_address = _rgba_blend_normal(*src_address, color, opacity);
}); });
@ -1976,7 +1971,7 @@ static void ink_hline16_replace(int x1, int y, int x2, ToolData *data)
int opacity = data->opacity; int opacity = data->opacity;
DEFINE_INK_PROCESSING_SRCDST DEFINE_INK_PROCESSING_SRCDST
(ase_uint16, (GrayscaleTraits,
if (*src_address == other_color) { if (*src_address == other_color) {
*dst_address = _graya_blend_normal(*src_address, color, opacity); *dst_address = _graya_blend_normal(*src_address, color, opacity);
}); });
@ -1991,7 +1986,7 @@ static void ink_hline8_replace(int x1, int y, int x2, ToolData *data)
int opacity = data->opacity; int opacity = data->opacity;
DEFINE_INK_PROCESSING_SRCDST DEFINE_INK_PROCESSING_SRCDST
(ase_uint8, (IndexedTraits,
if (*src_address == other_color) { if (*src_address == other_color) {
c = _rgba_blend_normal(pal->color[*src_address], tc, opacity); c = _rgba_blend_normal(pal->color[*src_address], tc, opacity);
*dst_address = orig_rgb_map->data *dst_address = orig_rgb_map->data
@ -2039,7 +2034,7 @@ static void ink_hline32_jumble(int x1, int y, int x2, ToolData *data)
int u, v, color; int u, v, color;
DEFINE_INK_PROCESSING_SRCDST DEFINE_INK_PROCESSING_SRCDST
(ase_uint32, (RgbTraits,
{ {
JUMBLE_XY_IN_UV(); JUMBLE_XY_IN_UV();
*dst_address = _rgba_blend_MERGE(*src_address, color, opacity); *dst_address = _rgba_blend_MERGE(*src_address, color, opacity);
@ -2056,7 +2051,7 @@ static void ink_hline16_jumble(int x1, int y, int x2, ToolData *data)
int u, v, color; int u, v, color;
DEFINE_INK_PROCESSING_SRCDST DEFINE_INK_PROCESSING_SRCDST
(ase_uint16, (GrayscaleTraits,
{ {
JUMBLE_XY_IN_UV(); JUMBLE_XY_IN_UV();
*dst_address = _graya_blend_MERGE(*src_address, color, opacity); *dst_address = _graya_blend_MERGE(*src_address, color, opacity);
@ -2075,7 +2070,7 @@ static void ink_hline8_jumble(int x1, int y, int x2, ToolData *data)
int u, v, color; int u, v, color;
DEFINE_INK_PROCESSING_SRCDST DEFINE_INK_PROCESSING_SRCDST
(ase_uint8, (IndexedTraits,
{ {
JUMBLE_XY_IN_UV(); JUMBLE_XY_IN_UV();

View File

@ -53,7 +53,7 @@ enum {
BLEND_MODE_MAX, BLEND_MODE_MAX,
}; };
typedef int (*BLEND_COLOR) (int back, int front, int opacity); typedef int (*BLEND_COLOR)(int back, int front, int opacity);
extern BLEND_COLOR _rgba_blenders[]; extern BLEND_COLOR _rgba_blenders[];
extern BLEND_COLOR _graya_blenders[]; extern BLEND_COLOR _graya_blenders[];

View File

@ -52,7 +52,7 @@
\ \
memcpy((col)->ptr, \ memcpy((col)->ptr, \
(col)->data, \ (col)->data, \
DIRTY_LINE_SIZE((col)->w)); \ dirty_line_size(dirty, (col)->w)); \
} }
#define JOIN_WITH_NEXT(row, col, u) \ #define JOIN_WITH_NEXT(row, col, u) \
@ -110,7 +110,7 @@
\ \
row->col[u].w = to_x2 - row->col[u].x + 1; \ row->col[u].w = to_x2 - row->col[u].x + 1; \
row->col[u].data = jrealloc(row->col[u].data, \ row->col[u].data = jrealloc(row->col[u].data, \
DIRTY_LINE_SIZE(row->col[u].w)); dirty_line_size(dirty, row->col[u].w));
typedef struct AlgoData typedef struct AlgoData
{ {
@ -174,7 +174,7 @@ Dirty* dirty_new_copy(Dirty* src)
dst->row[v].col[u].flags = src->row[v].col[u].flags; dst->row[v].col[u].flags = src->row[v].col[u].flags;
dst->row[v].col[u].ptr = src->row[v].col[u].ptr; dst->row[v].col[u].ptr = src->row[v].col[u].ptr;
size = dst->row[v].col[u].w << IMAGE_SHIFT(dst->image); size = dst->row[v].col[u].w << image_shift(dst->image);
dst->row[v].col[u].data = jmalloc(size); dst->row[v].col[u].data = jmalloc(size);
@ -268,9 +268,8 @@ void dirty_putpixel(Dirty* dirty, int x, int y)
return; return;
if ((dirty->mask->bitmap) && if ((dirty->mask->bitmap) &&
!(dirty->mask->bitmap->method->getpixel(dirty->mask->bitmap, !(dirty->mask->bitmap->getpixel(x-dirty->mask->x,
x-dirty->mask->x, y-dirty->mask->y)))
y-dirty->mask->y)))
return; return;
} }
@ -310,7 +309,7 @@ void dirty_putpixel(Dirty* dirty, int x, int y)
if (u < row->cols-1 && x+1 == (col+1)->x) if (u < row->cols-1 && x+1 == (col+1)->x)
JOIN_WITH_NEXT(row, col, u); JOIN_WITH_NEXT(row, col, u);
col->data = jrealloc(col->data, DIRTY_LINE_SIZE(col->w)); col->data = jrealloc(col->data, dirty_line_size(dirty, col->w));
return; return;
} }
/* the pixel is to left of the column */ /* the pixel is to left of the column */
@ -319,9 +318,9 @@ void dirty_putpixel(Dirty* dirty, int x, int y)
--col->x; --col->x;
++col->w; ++col->w;
col->data = jrealloc(col->data, DIRTY_LINE_SIZE(col->w)); col->data = jrealloc(col->data, dirty_line_size(dirty, col->w));
col->ptr = IMAGE_ADDRESS(dirty->image, x, y); col->ptr = image_address(dirty->image, x, y);
return; return;
} }
/* the next column is more too far */ /* the next column is more too far */
@ -335,8 +334,8 @@ void dirty_putpixel(Dirty* dirty, int x, int y)
col->x = x; col->x = x;
col->w = 1; col->w = 1;
col->flags = 0; col->flags = 0;
col->data = jmalloc(DIRTY_LINE_SIZE(1)); col->data = jmalloc(dirty_line_size(dirty, 1));
col->ptr = IMAGE_ADDRESS(dirty->image, x, y); col->ptr = image_address(dirty->image, x, y);
} }
void dirty_hline(Dirty* dirty, int x1, int y, int x2) void dirty_hline(Dirty* dirty, int x1, int y, int x2)
@ -405,15 +404,13 @@ void dirty_hline(Dirty* dirty, int x1, int y, int x2)
if (dirty->mask->bitmap) { if (dirty->mask->bitmap) {
for (; x1<=x2; ++x1) for (; x1<=x2; ++x1)
if (dirty->mask->bitmap->method->getpixel(dirty->mask->bitmap, if (dirty->mask->bitmap->getpixel(x1-dirty->mask->x,
x1-dirty->mask->x, y-dirty->mask->y))
y-dirty->mask->y))
break; break;
for (; x2>=x1; x2--) for (; x2>=x1; x2--)
if (dirty->mask->bitmap->method->getpixel(dirty->mask->bitmap, if (dirty->mask->bitmap->getpixel(x2-dirty->mask->x,
x2-dirty->mask->x, y-dirty->mask->y))
y-dirty->mask->y))
break; break;
} }
@ -446,9 +443,8 @@ void dirty_hline(Dirty* dirty, int x1, int y, int x2)
if (dirty->mask && dirty->mask->bitmap) { if (dirty->mask && dirty->mask->bitmap) {
for (x=x1; x<=x2; ++x) { for (x=x1; x<=x2; ++x) {
if (!dirty->mask->bitmap->method->getpixel(dirty->mask->bitmap, if (!dirty->mask->bitmap->getpixel(x-dirty->mask->x,
x-dirty->mask->x, y-dirty->mask->y)) {
y-dirty->mask->y)) {
continue; continue;
} }
@ -471,7 +467,7 @@ void dirty_hline(Dirty* dirty, int x1, int y, int x2)
memcpy((col+1)->ptr, memcpy((col+1)->ptr,
(col+1)->data, (col+1)->data,
DIRTY_LINE_SIZE((col+1)->w)); dirty_line_size(dirty, (col+1)->w));
} }
col->w += (col+1)->w; col->w += (col+1)->w;
@ -489,7 +485,7 @@ void dirty_hline(Dirty* dirty, int x1, int y, int x2)
col = row->col+u; col = row->col+u;
} }
col->data = jrealloc(col->data, DIRTY_LINE_SIZE(col->w)); col->data = jrealloc(col->data, dirty_line_size(dirty, col->w));
goto done; goto done;
} }
/* the pixel is in the left of the column */ /* the pixel is in the left of the column */
@ -499,13 +495,13 @@ void dirty_hline(Dirty* dirty, int x1, int y, int x2)
memcpy(col->ptr, memcpy(col->ptr,
col->data, col->data,
DIRTY_LINE_SIZE(col->w)); dirty_line_size(dirty, col->w));
} }
--col->x; --col->x;
++col->w; ++col->w;
col->data = jrealloc(col->data, DIRTY_LINE_SIZE(col->w)); col->data = jrealloc(col->data, dirty_line_size(dirty, col->w));
col->ptr = IMAGE_ADDRESS(dirty->image, x, y); col->ptr = image_address(dirty->image, x, y);
goto done; goto done;
} }
else if (x < col->x) else if (x < col->x)
@ -523,8 +519,8 @@ void dirty_hline(Dirty* dirty, int x1, int y, int x2)
col->x = x; col->x = x;
col->w = 1; col->w = 1;
col->flags = 0; col->flags = 0;
col->data = jmalloc(DIRTY_LINE_SIZE(1)); col->data = jmalloc(dirty_line_size(dirty, 1));
col->ptr = IMAGE_ADDRESS(dirty->image, x, y); col->ptr = image_address(dirty->image, x, y);
done:; done:;
} }
@ -556,11 +552,11 @@ void dirty_hline(Dirty* dirty, int x1, int y, int x2)
/* extend to left */ /* extend to left */
col->w += col->x - x1; col->w += col->x - x1;
col->x = x1; col->x = x1;
col->ptr = IMAGE_ADDRESS(dirty->image, x1, y); col->ptr = image_address(dirty->image, x1, y);
/* inside the column */ /* inside the column */
if (x2 <= col->x+col->w-1) { if (x2 <= col->x+col->w-1) {
col->data = jrealloc(col->data, DIRTY_LINE_SIZE(col->w)); col->data = jrealloc(col->data, dirty_line_size(dirty, col->w));
return; return;
} }
/* extend this column to "x2" */ /* extend this column to "x2" */
@ -580,8 +576,8 @@ void dirty_hline(Dirty* dirty, int x1, int y, int x2)
col->x = x1; col->x = x1;
col->w = x2-x1+1; col->w = x2-x1+1;
col->flags = 0; col->flags = 0;
col->data = jmalloc(DIRTY_LINE_SIZE(col->w)); col->data = jmalloc(dirty_line_size(dirty, col->w));
col->ptr = IMAGE_ADDRESS(dirty->image, x1, y); col->ptr = image_address(dirty->image, x1, y);
} }
} }
@ -645,7 +641,7 @@ void dirty_line_brush(Dirty* dirty, Brush* brush, int x1, int y1, int x2, int y2
void dirty_save_image_data(Dirty* dirty) void dirty_save_image_data(Dirty* dirty)
{ {
register int v, u, shift = IMAGE_SHIFT(dirty->image); register int v, u, shift = image_shift(dirty->image);
for (v=0; v<dirty->rows; ++v) for (v=0; v<dirty->rows; ++v)
for (u=0; u<dirty->row[v].cols; ++u) { for (u=0; u<dirty->row[v].cols; ++u) {
@ -666,7 +662,7 @@ void dirty_restore_image_data(Dirty* dirty)
register DirtyCol* col; register DirtyCol* col;
DirtyRow* rowend; DirtyRow* rowend;
DirtyCol* colend; DirtyCol* colend;
int shift = IMAGE_SHIFT(dirty->image); int shift = image_shift(dirty->image);
row = dirty->row; row = dirty->row;
rowend = row+dirty->rows; rowend = row+dirty->rows;

View File

@ -19,6 +19,8 @@
#ifndef RASTER_DIRTY_H #ifndef RASTER_DIRTY_H
#define RASTER_DIRTY_H #define RASTER_DIRTY_H
#include "raster/image.h"
struct Brush; struct Brush;
class Image; class Image;
class Mask; class Mask;
@ -26,9 +28,6 @@ class Mask;
#define DIRTY_VALID_COLUMN 1 #define DIRTY_VALID_COLUMN 1
#define DIRTY_MUSTBE_UPDATED 2 #define DIRTY_MUSTBE_UPDATED 2
#define DIRTY_LINE_SIZE(width) \
(IMAGE_LINE_SIZE(dirty->image, width))
struct DirtyCol struct DirtyCol
{ {
int x, w; int x, w;
@ -75,5 +74,10 @@ void dirty_save_image_data(Dirty* dirty);
void dirty_restore_image_data(Dirty* dirty); void dirty_restore_image_data(Dirty* dirty);
void dirty_swap(Dirty* dirty); void dirty_swap(Dirty* dirty);
inline int dirty_line_size(Dirty* dirty, int width)
{
return image_line_size(dirty->image, width);
}
#endif /* RASTER_DIRTY_H */ #endif /* RASTER_DIRTY_H */

View File

@ -20,8 +20,6 @@
#include <assert.h> #include <assert.h>
#include <allegro.h> #include <allegro.h>
/* #include <allegro/color.h> */
/* #include <allegro/gfx.h> */
#include <string.h> #include <string.h>
#include <stdexcept> #include <stdexcept>
@ -29,26 +27,10 @@
#include "raster/blend.h" #include "raster/blend.h"
#include "raster/brush.h" #include "raster/brush.h"
#include "raster/image.h" #include "raster/image.h"
#include "raster/image_impl.h"
#ifndef USE_ALLEGRO_IMAGE #include "raster/palette.h"
#include "imgbit.cpp"
#include "imggray.cpp"
#include "imgindex.cpp"
#include "imgrgb.cpp"
static ImageMethods *image_methods[] =
{
&rgb_methods, /* IMAGE_RGB */
&grayscale_methods, /* IMAGE_GRAYSCALE */
&indexed_methods, /* IMAGE_INDEXED */
&bitmap_methods, /* IMAGE_BITMAP */
};
#else
#include "imgalleg.c"
#endif
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
Image::Image(int imgtype, int w, int h) Image::Image(int imgtype, int w, int h)
: GfxObj(GFXOBJ_IMAGE) : GfxObj(GFXOBJ_IMAGE)
@ -56,36 +38,27 @@ Image::Image(int imgtype, int w, int h)
this->imgtype = imgtype; this->imgtype = imgtype;
this->w = w; this->w = w;
this->h = h; this->h = h;
#ifndef USE_ALLEGRO_IMAGE
this->method = image_methods[imgtype];
#else
this->method = &alleg_methods;
#endif
this->dat = NULL; this->dat = NULL;
this->line = NULL; this->line = NULL;
#ifdef USE_ALLEGRO_IMAGE
this->bmp = NULL;
#endif
assert(this->method);
this->method->init(this);
} }
Image::~Image() Image::~Image()
{ {
#ifndef USE_ALLEGRO_IMAGE
if (this->dat) delete[] this->dat; if (this->dat) delete[] this->dat;
if (this->line) delete[] this->line; if (this->line) delete[] this->line;
#else
destroy_bitmap(this->bmp);
#endif
} }
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
Image* image_new(int imgtype, int w, int h) Image* image_new(int imgtype, int w, int h)
{ {
return new Image(imgtype, w, h); switch (imgtype) {
case IMAGE_RGB: return new ImageImpl<RgbTraits>(w, h);
case IMAGE_GRAYSCALE: return new ImageImpl<GrayscaleTraits>(w, h);
case IMAGE_INDEXED: return new ImageImpl<IndexedTraits>(w, h);
case IMAGE_BITMAP: return new ImageImpl<BitmapTraits>(w, h);
}
return NULL;
} }
Image* image_new_copy(const Image* image) Image* image_new_copy(const Image* image)
@ -114,7 +87,7 @@ int image_depth(Image* image)
int image_getpixel(const Image* image, int x, int y) int image_getpixel(const Image* image, int x, int y)
{ {
if ((x >= 0) && (y >= 0) && (x < image->w) && (y < image->h)) if ((x >= 0) && (y >= 0) && (x < image->w) && (y < image->h))
return image->method->getpixel(image, x, y); return image->getpixel(x, y);
else else
return -1; return -1;
} }
@ -122,22 +95,22 @@ int image_getpixel(const Image* image, int x, int y)
void image_putpixel(Image* image, int x, int y, int color) void image_putpixel(Image* image, int x, int y, int color)
{ {
if ((x >= 0) && (y >= 0) && (x < image->w) && (y < image->h)) if ((x >= 0) && (y >= 0) && (x < image->w) && (y < image->h))
image->method->putpixel (image, x, y, color); image->putpixel(x, y, color);
} }
void image_clear(Image* image, int color) void image_clear(Image* image, int color)
{ {
image->method->clear (image, color); image->clear(color);
} }
void image_copy(Image* dst, const Image* src, int x, int y) void image_copy(Image* dst, const Image* src, int x, int y)
{ {
dst->method->copy (dst, src, x, y); dst->copy(src, x, y);
} }
void image_merge(Image* dst, const Image* src, int x, int y, int opacity, int blend_mode) void image_merge(Image* dst, const Image* src, int x, int y, int opacity, int blend_mode)
{ {
dst->method->merge(dst, src, x, y, opacity, blend_mode); dst->merge(src, x, y, opacity, blend_mode);
} }
Image* image_crop(const Image* image, int x, int y, int w, int h, int bgcolor) Image* image_crop(const Image* image, int x, int y, int w, int h, int bgcolor)
@ -169,7 +142,7 @@ void image_hline(Image* image, int x1, int y, int x2, int color)
if (x1 < 0) x1 = 0; if (x1 < 0) x1 = 0;
if (x2 >= image->w) x2 = image->w-1; if (x2 >= image->w) x2 = image->w-1;
image->method->hline(image, x1, y, x2, color); image->hline(x1, y, x2, color);
} }
void image_vline(Image* image, int x, int y1, int y2, int color) void image_vline(Image* image, int x, int y1, int y2, int color)
@ -189,7 +162,7 @@ void image_vline(Image* image, int x, int y1, int y2, int color)
if (y2 >= image->h) y2 = image->h-1; if (y2 >= image->h) y2 = image->h-1;
for (t=y1; t<=y2; t++) for (t=y1; t<=y2; t++)
image->method->putpixel(image, x, t, color); image->putpixel(x, t, color);
} }
void image_rect(Image* image, int x1, int y1, int x2, int y2, int color) void image_rect(Image* image, int x1, int y1, int x2, int y2, int color)
@ -243,7 +216,7 @@ void image_rectfill(Image* image, int x1, int y1, int x2, int y2, int color)
if (x2 >= image->w) x2 = image->w-1; if (x2 >= image->w) x2 = image->w-1;
if (y2 >= image->h) y2 = image->h-1; if (y2 >= image->h) y2 = image->h-1;
image->method->rectfill(image, x1, y1, x2, y2, color); image->rectfill(x1, y1, x2, y2, color);
} }
typedef struct Data typedef struct Data
@ -349,12 +322,12 @@ void image_ellipsefill(Image* image, int x1, int y1, int x2, int y2, int color)
Allegro <-> Image Allegro <-> Image
*********************************************************************/ *********************************************************************/
void image_to_allegro(Image* image, BITMAP *bmp, int x, int y) void image_to_allegro(const Image* image, BITMAP *bmp, int x, int y)
{ {
image->method->to_allegro(image, bmp, x, y); image->to_allegro(bmp, x, y);
} }
void image_convert(Image* dst, const Image* src) void image_convert(const Image* src, Image* dst)
{ {
int c, x, y, w, h; int c, x, y, w, h;
float hue, s, v; float hue, s, v;
@ -378,14 +351,14 @@ void image_convert(Image* dst, const Image* src)
case IMAGE_GRAYSCALE: case IMAGE_GRAYSCALE:
for (y=0; y<h; y++) { for (y=0; y<h; y++) {
for (x=0; x<w; x++) { for (x=0; x<w; x++) {
c = src->method->getpixel(src, x, y); c = image_getpixel_fast<RgbTraits>(src, x, y);
rgb_to_hsv(_rgba_getr(c), rgb_to_hsv(_rgba_getr(c),
_rgba_getg(c), _rgba_getg(c),
_rgba_getb(c), &hue, &s, &v); _rgba_getb(c), &hue, &s, &v);
v = v * 255.0f; v = v * 255.0f;
dst->method->putpixel(dst, x, y, image_putpixel_fast<GrayscaleTraits>(dst, x, y,
_graya((int)MID(0, v, 255), _graya((int)MID(0, v, 255),
_rgba_geta(c))); _rgba_geta(c)));
} }
} }
break; break;
@ -394,14 +367,14 @@ void image_convert(Image* dst, const Image* src)
case IMAGE_INDEXED: case IMAGE_INDEXED:
for (y=0; y<h; y++) { for (y=0; y<h; y++) {
for (x=0; x<w; x++) { for (x=0; x<w; x++) {
c = src->method->getpixel(src, x, y); c = image_getpixel_fast<RgbTraits>(src, x, y);
if (!_rgba_geta (c)) if (!_rgba_geta (c))
dst->method->putpixel(dst, x, y, 0); image_putpixel_fast<IndexedTraits>(dst, x, y, 0);
else else
dst->method->putpixel(dst, x, y, image_putpixel_fast<IndexedTraits>(dst, x, y,
makecol8(_rgba_getr(c), makecol8(_rgba_getr(c),
_rgba_getg(c), _rgba_getg(c),
_rgba_getb(c))); _rgba_getb(c)));
} }
} }
break; break;
@ -415,12 +388,12 @@ void image_convert(Image* dst, const Image* src)
case IMAGE_RGB: case IMAGE_RGB:
for (y=0; y<h; y++) { for (y=0; y<h; y++) {
for (x=0; x<w; x++) { for (x=0; x<w; x++) {
c = src->method->getpixel(src, x, y); c = image_getpixel_fast<GrayscaleTraits>(src, x, y);
dst->method->putpixel(dst, x, y, image_putpixel_fast<RgbTraits>(dst, x, y,
_rgba(_graya_getv(c), _rgba(_graya_getv(c),
_graya_getv(c), _graya_getv(c),
_graya_getv(c), _graya_getv(c),
_graya_geta(c))); _graya_geta(c)));
} }
} }
break; break;
@ -429,14 +402,14 @@ void image_convert(Image* dst, const Image* src)
case IMAGE_INDEXED: case IMAGE_INDEXED:
for (y=0; y<h; y++) { for (y=0; y<h; y++) {
for (x=0; x<w; x++) { for (x=0; x<w; x++) {
c = src->method->getpixel(src, x, y); c = image_getpixel_fast<GrayscaleTraits>(src, x, y);
if (!_graya_geta(c)) if (!_graya_geta(c))
dst->method->putpixel(dst, x, y, 0); image_putpixel_fast<IndexedTraits>(dst, x, y, 0);
else else
dst->method->putpixel(dst, x, y, image_putpixel_fast<IndexedTraits>(dst, x, y,
makecol8(_graya_getv(c), makecol8(_graya_getv(c),
_graya_getv(c), _graya_getv(c),
_graya_getv(c))); _graya_getv(c)));
} }
} }
break; break;
@ -450,14 +423,14 @@ void image_convert(Image* dst, const Image* src)
case IMAGE_RGB: case IMAGE_RGB:
for (y=0; y<h; y++) { for (y=0; y<h; y++) {
for (x=0; x<w; x++) { for (x=0; x<w; x++) {
c = src->method->getpixel(src, x, y); c = image_getpixel_fast<IndexedTraits>(src, x, y);
if (!c) if (!c)
dst->method->putpixel(dst, x, y, 0); image_putpixel_fast<RgbTraits>(dst, x, y, 0);
else else
dst->method->putpixel(dst, x, y, image_putpixel_fast<RgbTraits>(dst, x, y,
_rgba(getr8(c), _rgba(getr8(c),
getg8(c), getg8(c),
getb8(c), 255)); getb8(c), 255));
} }
} }
break; break;
@ -466,14 +439,14 @@ void image_convert(Image* dst, const Image* src)
case IMAGE_GRAYSCALE: case IMAGE_GRAYSCALE:
for (y=0; y<h; y++) { for (y=0; y<h; y++) {
for (x=0; x<w; x++) { for (x=0; x<w; x++) {
c = src->method->getpixel(src, x, y); c = image_getpixel_fast<GrayscaleTraits>(src, x, y);
if (!c) if (!c)
dst->method->putpixel(dst, x, y, 0); image_putpixel_fast<GrayscaleTraits>(dst, x, y, 0);
else { else {
rgb_to_hsv(getr8(c), getg8(c), getb8(c), &hue, &s, &v); rgb_to_hsv(getr8(c), getg8(c), getb8(c), &hue, &s, &v);
v = v * 255.0f; v = v * 255.0f;
dst->method->putpixel(dst, x, y, image_putpixel_fast<GrayscaleTraits>(dst, x, y,
_graya((int)MID(0, v, 255), 255)); _graya((int)MID(0, v, 255), 255));
} }
} }
} }
@ -483,6 +456,107 @@ void image_convert(Image* dst, const Image* src)
} }
} }
void image_resize(const Image* src, Image* dst, ResizeMethod method, Palette* pal, RGB_MAP* rgb_map)
{
switch (method) {
// TODO optimize this
case RESIZE_METHOD_NEAREST_NEIGHBOR: {
ase_uint32 color;
double u, v, du, dv;
int x, y;
u = v = 0.0;
du = src->w * 1.0 / dst->w;
dv = src->h * 1.0 / dst->h;
for (y=0; y<dst->h; ++y) {
for (x=0; x<dst->w; ++x) {
color = src->getpixel(MID(0, u, src->w-1),
MID(0, v, src->h-1));
dst->putpixel(x, y, color);
u += du;
}
u = 0.0;
v += dv;
}
break;
}
// TODO optimize this
case RESIZE_METHOD_BILINEAR: {
ase_uint32 color[4], dst_color;
double u, v, du, dv;
int x, y;
u = v = 0.0;
du = src->w * 1.0 / dst->w;
dv = src->h * 1.0 / dst->h;
for (y=0; y<dst->h; ++y) {
for (x=0; x<dst->w; ++x) {
int u_floor = floor(u);
int v_floor = floor(v);
color[0] = src->getpixel(MID(0, u_floor, src->w-1),
MID(0, v_floor, src->h-1));
color[1] = src->getpixel(MID(0, u_floor+1, src->w-1),
MID(0, v_floor, src->h-1));
color[2] = src->getpixel(MID(0, u_floor, src->w-1),
MID(0, v_floor+1, src->h-1));
color[3] = src->getpixel(MID(0, u_floor+1, src->w-1),
MID(0, v_floor+1, src->h-1));
double u1 = u - u_floor;
double v1 = v - v_floor;
double u2 = 1 - u1;
double v2 = 1 - v1;
switch (dst->imgtype) {
case IMAGE_RGB: {
int r = ((_rgba_getr(color[0])*u2 + _rgba_getr(color[1])*u1)*v2 +
(_rgba_getr(color[2])*u2 + _rgba_getr(color[3])*u1)*v1);
int g = ((_rgba_getg(color[0])*u2 + _rgba_getg(color[1])*u1)*v2 +
(_rgba_getg(color[2])*u2 + _rgba_getg(color[3])*u1)*v1);
int b = ((_rgba_getb(color[0])*u2 + _rgba_getb(color[1])*u1)*v2 +
(_rgba_getb(color[2])*u2 + _rgba_getb(color[3])*u1)*v1);
int a = ((_rgba_geta(color[0])*u2 + _rgba_geta(color[1])*u1)*v2 +
(_rgba_geta(color[2])*u2 + _rgba_geta(color[3])*u1)*v1);
dst_color = _rgba(r, g, b, a);
break;
}
case IMAGE_GRAYSCALE: {
int v = ((_graya_getv(color[0])*u2 + _graya_getv(color[1])*u1)*v2 +
(_graya_getv(color[2])*u2 + _graya_getv(color[3])*u1)*v1);
int a = ((_graya_geta(color[0])*u2 + _graya_geta(color[1])*u1)*v2 +
(_graya_geta(color[2])*u2 + _graya_geta(color[3])*u1)*v1);
dst_color = _graya(v, a);
break;
}
case IMAGE_INDEXED: {
int r = ((_rgba_getr(pal->color[color[0]])*u2 + _rgba_getr(pal->color[color[1]])*u1)*v2 +
(_rgba_getr(pal->color[color[2]])*u2 + _rgba_getr(pal->color[color[3]])*u1)*v1);
int g = ((_rgba_getg(pal->color[color[0]])*u2 + _rgba_getg(pal->color[color[1]])*u1)*v2 +
(_rgba_getg(pal->color[color[2]])*u2 + _rgba_getg(pal->color[color[3]])*u1)*v1);
int b = ((_rgba_getb(pal->color[color[0]])*u2 + _rgba_getb(pal->color[color[1]])*u1)*v2 +
(_rgba_getb(pal->color[color[2]])*u2 + _rgba_getb(pal->color[color[3]])*u1)*v1);
int a = ((_rgba_geta(pal->color[color[0]])*u2 + _rgba_geta(pal->color[color[1]])*u1)*v2 +
(_rgba_geta(pal->color[color[2]])*u2 + _rgba_geta(pal->color[color[3]])*u1)*v1);
dst_color = a > 127 ? rgb_map->data[r>>3][g>>3][b>>3]: 0;
break;
}
}
dst->putpixel(x, y, dst_color);
u += du;
}
u = 0.0;
v += dv;
}
break;
}
}
}
int image_count_diff(const Image* i1, const Image* i2) int image_count_diff(const Image* i1, const Image* i2)
{ {
int c, size, diff = 0; int c, size, diff = 0;
@ -552,7 +626,7 @@ bool image_shrink_rect(Image *image, int *x1, int *y1, int *x2, int *y2, int ref
do { \ do { \
for (u = u_begin; u u_op u_final; u u_add) { \ for (u = u_begin; u u_op u_final; u u_add) { \
for (v = v_begin; v v_op v_final; v v_add) { \ for (v = v_begin; v v_op v_final; v v_add) { \
if (image->method->getpixel (image, U, V) != refpixel) \ if (image->getpixel(U, V) != refpixel) \
break; \ break; \
} \ } \
if (v == v_final) \ if (v == v_final) \
@ -588,4 +662,3 @@ bool image_shrink_rect(Image *image, int *x1, int *y1, int *x2, int *y2, int ref
#undef SHRINK_SIDE #undef SHRINK_SIDE
} }

View File

@ -19,51 +19,13 @@
#ifndef RASTER_IMAGE_H #ifndef RASTER_IMAGE_H
#define RASTER_IMAGE_H #define RASTER_IMAGE_H
/* #define USE_ALLEGRO_IMAGE */ #include <allegro/color.h>
#include "raster/gfxobj.h" #include "raster/gfxobj.h"
#include "raster/blend.h"
#define _rgba_r_shift 0 class Palette;
#define _rgba_g_shift 8
#define _rgba_b_shift 16
#define _rgba_a_shift 24
#define _rgba_getr(c) (((c) >> _rgba_r_shift) & 0xff)
#define _rgba_getg(c) (((c) >> _rgba_g_shift) & 0xff)
#define _rgba_getb(c) (((c) >> _rgba_b_shift) & 0xff)
#define _rgba_geta(c) (((c) >> _rgba_a_shift) & 0xff)
#define _rgba(r,g,b,a) \
((ase_uint32)(((r) << _rgba_r_shift) | \
((g) << _rgba_g_shift) | \
((b) << _rgba_b_shift) | \
((a) << _rgba_a_shift)))
#define _graya_v_shift 0 // Image Types
#define _graya_a_shift 8
#define _graya_getv(c) (((c) >> _graya_v_shift) & 0xff)
#define _graya_geta(c) (((c) >> _graya_a_shift) & 0xff)
#define _graya(v,a) \
((ase_uint16)(((v) << _graya_v_shift) | \
((a) << _graya_a_shift)))
#define _image_bitmap_next_bit(d, a) \
if (d.rem < 7) \
d.rem++; \
else { \
a++; \
d.rem = 0; \
}
#define IMAGE_ADDRESS(image,x,y) \
((void *)((image)->line[(y)] + IMAGE_LINE_SIZE((image), (x)))) \
#define IMAGE_SHIFT(d) \
(((d)->imgtype == IMAGE_RGB)? 2: \
((d)->imgtype == IMAGE_GRAYSCALE)? 1: 0)
#define IMAGE_LINE_SIZE(image, width) \
((width) << IMAGE_SHIFT(image))
/* Image Types */
enum { enum {
IMAGE_RGB, IMAGE_RGB,
IMAGE_GRAYSCALE, IMAGE_GRAYSCALE,
@ -71,9 +33,12 @@ enum {
IMAGE_BITMAP IMAGE_BITMAP
}; };
enum ResizeMethod {
RESIZE_METHOD_NEAREST_NEIGHBOR,
RESIZE_METHOD_BILINEAR,
};
struct BITMAP; struct BITMAP;
/* struct Brush; */
struct ImageMethods;
class Image : public GfxObj class Image : public GfxObj
{ {
@ -82,27 +47,18 @@ public:
int w, h; int w, h;
ase_uint8* dat; /* pixmap data */ ase_uint8* dat; /* pixmap data */
ase_uint8** line; /* start of each scanline */ ase_uint8** line; /* start of each scanline */
ImageMethods* method;
#ifdef USE_ALLEGRO_IMAGE
BITMAP* bmp;
#endif
Image(int imgtype, int w, int h); Image(int imgtype, int w, int h);
virtual ~Image(); virtual ~Image();
};
struct ImageMethods virtual int getpixel(int x, int y) const = 0;
{ virtual void putpixel(int x, int y, int color) = 0;
void (*init)(Image* image); virtual void clear(int color) = 0;
int (*getpixel)(const Image* image, int x, int y); virtual void copy(const Image* src, int x, int y) = 0;
void (*putpixel)(Image* image, int x, int y, int color); virtual void merge(const Image* src, int x, int y, int opacity, int blend_mode) = 0;
void (*clear)(Image* image, int color); virtual void hline(int x1, int y, int x2, int color) = 0;
void (*copy)(Image* dst, const Image* src, int x, int y); virtual void rectfill(int x1, int y1, int x2, int y2, int color) = 0;
void (*merge)(Image* dst, const Image* src, int x, int y, int opacity, virtual void to_allegro(BITMAP* bmp, int x, int y) const = 0;
int blend_mode);
void (*hline)(Image* image, int x1, int y, int x2, int color);
void (*rectfill)(Image* image, int x1, int y1, int x2, int y2, int color);
void (*to_allegro)(const Image* image, BITMAP* bmp, int x, int y);
}; };
Image* image_new(int imgtype, int w, int h); Image* image_new(int imgtype, int w, int h);
@ -130,14 +86,29 @@ void image_line(Image* image, int x1, int y1, int x2, int y2, int color);
void image_ellipse(Image* image, int x1, int y1, int x2, int y2, int color); void image_ellipse(Image* image, int x1, int y1, int x2, int y2, int color);
void image_ellipsefill(Image* image, int x1, int y1, int x2, int y2, int color); void image_ellipsefill(Image* image, int x1, int y1, int x2, int y2, int color);
/* void image_putpixel_brush(Image* image, struct Brush *brush, int x, int y, int color); */ void image_to_allegro(const Image* image, BITMAP* bmp, int x, int y);
/* void image_hline_brush(Image* image, struct Brush *brush, int x1, int y, int x2, int color); */
/* void image_line_brush(Image* image, struct Brush *brush, int x1, int y1, int x2, int y2, int color); */
void image_to_allegro(Image* image, BITMAP* bmp, int x, int y); void image_convert(const Image* src, Image* dst);
void image_resize(const Image* src, Image* dst, ResizeMethod method, Palette* palette, RGB_MAP* rgb_map);
void image_convert(Image* dst, const Image* src);
int image_count_diff(const Image* i1, const Image* i2); int image_count_diff(const Image* i1, const Image* i2);
bool image_shrink_rect(Image *image, int *x1, int *y1, int *x2, int *y2, int refpixel); bool image_shrink_rect(Image *image, int *x1, int *y1, int *x2, int *y2, int refpixel);
inline int image_shift(Image* image)
{
return ((image->imgtype == IMAGE_RGB)? 2:
(image->imgtype == IMAGE_GRAYSCALE)? 1: 0);
}
inline int image_line_size(Image* image, int width)
{
return (width << image_shift(image));
}
inline void* image_address(Image* image, int x, int y)
{
return ((void *)(image->line[y] + image_line_size(image, x)));
}
#include "image_traits.h"
#endif /* RASTER_IMAGE_H */ #endif /* RASTER_IMAGE_H */

995
src/raster/image_impl.h Normal file
View File

@ -0,0 +1,995 @@
/* 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
*/
#ifndef RASTER_IMAGE_IMPL_H
#define RASTER_IMAGE_IMPL_H
#include <cassert>
template<class Traits>
class ImageImpl : public Image
{
typedef typename Traits::address_t address_t;
typedef typename Traits::const_address_t const_address_t;
inline address_t raw_pixels() {
return (address_t)dat;
}
inline const_address_t raw_pixels() const {
return (address_t)dat;
}
inline address_t line_address(int y) {
assert(y >= 0 && y < h);
return ((address_t*)line)[y];
}
inline const_address_t line_address(int y) const {
assert(y >= 0 && y < h);
return ((const_address_t*)line)[y];
}
public:
ImageImpl(int w, int h)
: Image(Traits::imgtype, w, h)
{
int bytes_per_line = Traits::scanline_size(w);
dat = new ase_uint8[bytes_per_line*h];
try {
line = (ase_uint8**)new address_t*[h];
}
catch (...) {
delete[] dat;
throw;
}
address_t addr = raw_pixels();
for (int y=0; y<h; ++y) {
((address_t*)line)[y] = addr;
addr = (address_t)(((ase_uint8*)addr) + bytes_per_line);
}
}
virtual int getpixel(int x, int y) const
{
return image_getpixel_fast<Traits>(this, x, y);
}
virtual void putpixel(int x, int y, int color)
{
image_putpixel_fast<Traits>(this, x, y, color);
}
virtual void clear(int color)
{
address_t addr = raw_pixels();
unsigned int c, size = w*h;
for (c=0; c<size; c++)
*(addr++) = color;
}
virtual void copy(const Image* src, int x, int y)
{
Image* dst = this;
address_t src_address;
address_t dst_address;
int xbeg, xend, xsrc;
int ybeg, yend, ysrc, ydst;
int bytes;
// clipping
xsrc = 0;
ysrc = 0;
xbeg = x;
ybeg = y;
xend = x+src->w-1;
yend = y+src->h-1;
if ((xend < 0) || (xbeg >= dst->w) ||
(yend < 0) || (ybeg >= dst->h))
return;
if (xbeg < 0) {
xsrc -= xbeg;
xbeg = 0;
}
if (ybeg < 0) {
ysrc -= ybeg;
ybeg = 0;
}
if (xend >= dst->w)
xend = dst->w-1;
if (yend >= dst->h)
yend = dst->h-1;
// copy process
bytes = Traits::scanline_size(xend - xbeg + 1);
for (ydst=ybeg; ydst<=yend; ydst++, ysrc++) {
src_address = ((ImageImpl<Traits>*)src)->line_address(ysrc)+xsrc;
dst_address = ((ImageImpl<Traits>*)dst)->line_address(ydst)+xbeg;
memcpy(dst_address, src_address, bytes);
}
}
virtual void merge(const Image* src, int x, int y, int opacity, int blend_mode)
{
BLEND_COLOR blender = Traits::get_blender(blend_mode);
Image* dst = this;
address_t src_address;
address_t dst_address;
int xbeg, xend, xsrc, xdst;
int ybeg, yend, ysrc, ydst;
// nothing to do
if (!opacity)
return;
// clipping
xsrc = 0;
ysrc = 0;
xbeg = x;
ybeg = y;
xend = x+src->w-1;
yend = y+src->h-1;
if ((xend < 0) || (xbeg >= dst->w) ||
(yend < 0) || (ybeg >= dst->h))
return;
if (xbeg < 0) {
xsrc -= xbeg;
xbeg = 0;
}
if (ybeg < 0) {
ysrc -= ybeg;
ybeg = 0;
}
if (xend >= dst->w)
xend = dst->w-1;
if (yend >= dst->h)
yend = dst->h-1;
// merge process
for (ydst=ybeg; ydst<=yend; ydst++, ysrc++) {
src_address = ((ImageImpl<Traits>*)src)->line_address(ysrc)+xsrc;
dst_address = ((ImageImpl<Traits>*)dst)->line_address(ydst)+xbeg;
for (xdst=xbeg; xdst<=xend; xdst++) {
*dst_address = (*blender)(*dst_address, *src_address, opacity);
dst_address++;
src_address++;
}
}
}
virtual void hline(int x1, int y, int x2, int color)
{
address_t addr = line_address(y)+x1;
for (int x=x1; x<=x2; ++x)
*(addr++) = color;
}
virtual void rectfill(int x1, int y1, int x2, int y2, int color)
{
address_t addr;
int x, y;
for (y=y1; y<=y2; ++y) {
addr = line_address(y)+x1;
for (x=x1; x<=x2; ++x)
*(addr++) = color;
}
}
virtual void to_allegro(BITMAP* bmp, int x, int y) const;
};
//////////////////////////////////////////////////////////////////////
// Specializations
void ImageImpl<IndexedTraits>::clear(int color)
{
memset(raw_pixels(), color, w*h);
}
/* if "color_map" is not NULL, it's used by the routine to merge the
source and the destionation pixels */
void ImageImpl<IndexedTraits>::merge(const Image* src, int x, int y, int opacity, int blend_mode)
{
Image* dst = this;
address_t src_address;
address_t dst_address;
int xbeg, xend, xsrc, xdst;
int ybeg, yend, ysrc, ydst;
// clipping
xsrc = 0;
ysrc = 0;
xbeg = x;
ybeg = y;
xend = x+src->w-1;
yend = y+src->h-1;
if ((xend < 0) || (xbeg >= dst->w) ||
(yend < 0) || (ybeg >= dst->h))
return;
if (xbeg < 0) {
xsrc -= xbeg;
xbeg = 0;
}
if (ybeg < 0) {
ysrc -= ybeg;
ybeg = 0;
}
if (xend >= dst->w)
xend = dst->w-1;
if (yend >= dst->h)
yend = dst->h-1;
// merge process
// direct copy
if (blend_mode == BLEND_MODE_COPY) {
for (ydst=ybeg; ydst<=yend; ydst++, ysrc++) {
src_address = ((ImageImpl<IndexedTraits>*)src)->line_address(ysrc)+xsrc;
dst_address = ((ImageImpl<IndexedTraits>*)dst)->line_address(ydst)+xbeg;
for (xdst=xbeg; xdst<=xend; xdst++) {
*dst_address = (*src_address);
dst_address++;
src_address++;
}
}
}
// with mask
else {
for (ydst=ybeg; ydst<=yend; ydst++, ysrc++) {
src_address = ((ImageImpl<IndexedTraits>*)src)->line_address(ysrc)+xsrc;
dst_address = ((ImageImpl<IndexedTraits>*)dst)->line_address(ydst)+xbeg;
for (xdst=xbeg; xdst<=xend; xdst++) {
if (*src_address) {
if (color_map)
*dst_address = color_map->data[*src_address][*dst_address];
else
*dst_address = (*src_address);
}
dst_address++;
src_address++;
}
}
}
}
void ImageImpl<BitmapTraits>::clear(int color)
{
memset(raw_pixels(), color ? 0xff: 0x00, ((w+7)/8) * h);
}
#define BITMAP_HLINE(op) \
for (x=x1; x<=x2; x++) { \
*addr op (1<<d.rem); \
_image_bitmap_next_bit(d, addr); \
}
void ImageImpl<BitmapTraits>::hline(int x1, int y, int x2, int color)
{
div_t d = div(x1, 8);
address_t addr = line_address(y)+d.quot;
int x;
if (color) {
BITMAP_HLINE( |= );
}
else {
BITMAP_HLINE( &= ~ );
}
}
void ImageImpl<BitmapTraits>::rectfill(int x1, int y1, int x2, int y2, int color)
{
div_t d, beg_d = div(x1, 8);
address_t addr;
int x, y;
if (color) {
for (y=y1; y<=y2; y++) {
d = beg_d;
addr = line_address(y)+d.quot;
BITMAP_HLINE( |= );
}
}
else {
for (y=y1; y<=y2; y++) {
d = beg_d;
addr = line_address(y)+d.quot;
BITMAP_HLINE( &= ~ );
}
}
}
void ImageImpl<BitmapTraits>::copy(const Image* src, int x, int y)
{
Image* dst = this;
address_t src_address;
address_t dst_address;
int xbeg, xend, xsrc, xdst;
int ybeg, yend, ysrc, ydst;
div_t src_d, src_beg_d;
div_t dst_d, dst_beg_d;
// clipping
xsrc = 0;
ysrc = 0;
xbeg = x;
ybeg = y;
xend = x+src->w-1;
yend = y+src->h-1;
if ((xend < 0) || (xbeg >= dst->w) ||
(yend < 0) || (ybeg >= dst->h))
return;
if (xbeg < 0) {
xsrc -= xbeg;
xbeg = 0;
}
if (ybeg < 0) {
ysrc -= ybeg;
ybeg = 0;
}
if (xend >= dst->w)
xend = dst->w-1;
if (yend >= dst->h)
yend = dst->h-1;
// copy process
src_beg_d = div(xsrc, 8);
dst_beg_d = div(xbeg, 8);
for (ydst=ybeg; ydst<=yend; ydst++, ysrc++) {
src_d = src_beg_d;
dst_d = dst_beg_d;
src_address = ((ImageImpl<BitmapTraits>*)src)->line_address(ysrc)+src_d.quot;
dst_address = ((ImageImpl<BitmapTraits>*)dst)->line_address(ydst)+dst_d.quot;
for (xdst=xbeg; xdst<=xend; xdst++) {
if ((*src_address & (1<<src_d.rem)))
*dst_address |= (1<<dst_d.rem);
else
*dst_address &= ~(1<<dst_d.rem);
_image_bitmap_next_bit(src_d, src_address);
_image_bitmap_next_bit(dst_d, dst_address);
}
}
}
void ImageImpl<BitmapTraits>::merge(const Image* src, int x, int y, int opacity, int blend_mode)
{
Image* dst = this;
address_t src_address;
address_t dst_address;
int xbeg, xend, xsrc, xdst;
int ybeg, yend, ysrc, ydst;
div_t src_d, src_beg_d;
div_t dst_d, dst_beg_d;
// clipping
xsrc = 0;
ysrc = 0;
xbeg = x;
ybeg = y;
xend = x+src->w-1;
yend = y+src->h-1;
if ((xend < 0) || (xbeg >= dst->w) ||
(yend < 0) || (ybeg >= dst->h))
return;
if (xbeg < 0) {
xsrc -= xbeg;
xbeg = 0;
}
if (ybeg < 0) {
ysrc -= ybeg;
ybeg = 0;
}
if (xend >= dst->w)
xend = dst->w-1;
if (yend >= dst->h)
yend = dst->h-1;
// copy process
src_beg_d = div(xsrc, 8);
dst_beg_d = div(xbeg, 8);
for (ydst=ybeg; ydst<=yend; ydst++, ysrc++) {
src_d = src_beg_d;
dst_d = dst_beg_d;
src_address = ((ImageImpl<BitmapTraits>*)src)->line_address(ysrc)+src_d.quot;
dst_address = ((ImageImpl<BitmapTraits>*)dst)->line_address(ydst)+dst_d.quot;
for (xdst=xbeg; xdst<=xend; xdst++) {
if ((*src_address & (1<<src_d.rem)))
*dst_address |= (1<<dst_d.rem);
_image_bitmap_next_bit(src_d, src_address);
_image_bitmap_next_bit(dst_d, dst_address);
}
}
}
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);
}
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);
}
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);
}
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

235
src/raster/image_traits.h Normal file
View File

@ -0,0 +1,235 @@
/* 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
*/
#ifndef RASTER_IMAGE_TRAITS_H
#define RASTER_IMAGE_TRAITS_H
#include <cassert>
//////////////////////////////////////////////////////////////////////
// RGBA
#define _rgba_r_shift 0
#define _rgba_g_shift 8
#define _rgba_b_shift 16
#define _rgba_a_shift 24
inline ase_uint8 _rgba_getr(ase_uint32 c)
{
return (c >> _rgba_r_shift) & 0xff;
}
inline ase_uint8 _rgba_getg(ase_uint32 c)
{
return (c >> _rgba_g_shift) & 0xff;
}
inline ase_uint8 _rgba_getb(ase_uint32 c)
{
return (c >> _rgba_b_shift) & 0xff;
}
inline ase_uint8 _rgba_geta(ase_uint32 c)
{
return (c >> _rgba_a_shift) & 0xff;
}
inline ase_uint32 _rgba(ase_uint8 r, ase_uint8 g, ase_uint8 b, ase_uint8 a)
{
return ((r << _rgba_r_shift) |
(g << _rgba_g_shift) |
(b << _rgba_b_shift) |
(a << _rgba_a_shift));
}
struct RgbTraits
{
enum {
imgtype = IMAGE_RGB,
bits_per_pixel = 32,
bytes_per_pixel = 4,
channels = 4,
has_alpha = true,
is_binary = false,
};
typedef ase_uint32 pixel_t;
typedef pixel_t* address_t;
typedef const pixel_t* const_address_t;
static inline int scanline_size(int w)
{
return bytes_per_pixel*w;
}
static inline BLEND_COLOR get_blender(int blend_mode)
{
assert(blend_mode >= 0 && blend_mode < BLEND_MODE_MAX);
return _rgba_blenders[blend_mode];
}
};
//////////////////////////////////////////////////////////////////////
// Grayscale
#define _graya_v_shift 0
#define _graya_a_shift 8
inline ase_uint8 _graya_getv(ase_uint16 c)
{
return (c >> _graya_v_shift) & 0xff;
}
inline ase_uint8 _graya_geta(ase_uint16 c)
{
return (c >> _graya_a_shift) & 0xff;
}
inline ase_uint16 _graya(ase_uint8 v, ase_uint8 a)
{
return ((v << _graya_v_shift) |
(a << _graya_a_shift));
}
struct GrayscaleTraits
{
enum {
imgtype = IMAGE_GRAYSCALE,
bits_per_pixel = 16,
bytes_per_pixel = 2,
channels = 2,
has_alpha = true,
is_binary = false,
};
typedef ase_uint16 pixel_t;
typedef pixel_t* address_t;
typedef const pixel_t* const_address_t;
static inline int scanline_size(int w)
{
return bytes_per_pixel*w;
}
static inline BLEND_COLOR get_blender(int blend_mode)
{
assert(blend_mode >= 0 && blend_mode < BLEND_MODE_MAX);
return _graya_blenders[blend_mode];
}
};
//////////////////////////////////////////////////////////////////////
// Indexed
struct IndexedTraits
{
enum {
imgtype = IMAGE_INDEXED,
bits_per_pixel = 8,
bytes_per_pixel = 1,
channels = 1,
has_alpha = false,
is_binary = false,
};
typedef ase_uint8 pixel_t;
typedef pixel_t* address_t;
typedef const pixel_t* const_address_t;
static inline int scanline_size(int w)
{
return bytes_per_pixel*w;
}
};
//////////////////////////////////////////////////////////////////////
// Bitmap
struct BitmapTraits
{
enum {
imgtype = IMAGE_BITMAP,
bits_per_pixel = 1,
bytes_per_pixel = 1,
channels = 1,
has_alpha = false,
is_binary = true,
};
typedef ase_uint8 pixel_t;
typedef pixel_t* address_t;
typedef const pixel_t* const_address_t;
static inline int scanline_size(int w)
{
return ((w+7)/8);
}
};
#define _image_bitmap_next_bit(d, a) \
if (d.rem < 7) \
d.rem++; \
else { \
a++; \
d.rem = 0; \
}
//////////////////////////////////////////////////////////////////////
template<class Traits>
inline typename Traits::pixel_t image_getpixel_fast(const Image* image, int x, int y)
{
assert(x >= 0 && x < image->w);
assert(y >= 0 && y < image->h);
return *((((typename Traits::pixel_t**)image->line)[y])+x);
}
template<class Traits>
inline void image_putpixel_fast(Image* image, int x, int y, typename Traits::pixel_t color)
{
assert(x >= 0 && x < image->w);
assert(y >= 0 && y < image->h);
*((((typename Traits::pixel_t**)image->line)[y])+x) = color;
}
template<>
inline BitmapTraits::pixel_t image_getpixel_fast<BitmapTraits>(const Image* image, int x, int y)
{
assert(x >= 0 && x < image->w);
assert(y >= 0 && y < image->h);
div_t d = div(x, 8);
return ((*(((BitmapTraits::pixel_t**)image->line)[y]+d.quot)) & (1<<d.rem)) ? 1: 0;
}
template<>
inline void image_putpixel_fast<BitmapTraits>(Image* image, int x, int y, BitmapTraits::pixel_t color)
{
assert(x >= 0 && x < image->w);
assert(y >= 0 && y < image->h);
div_t d = div(x, 8);
if (color)
*(((BitmapTraits::pixel_t**)image->line)[y]+d.quot) |= (1<<d.rem);
else
*(((BitmapTraits::pixel_t**)image->line)[y]+d.quot) &= ~(1<<d.rem);
}
#endif // RASTER_IMAGE_TRAITS_H

View File

@ -1,209 +0,0 @@
/* 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
*/
#undef BYTES
#undef LINES
#define BYTES(image) ((ase_uint8 *)image->dat)
#define LINES(image) ((ase_uint8 **)image->line)
static int alleg_init(Image *image)
{
static int _image_depth[] = { 32, 16, 8, 8 };
image->bmp = create_bitmap_ex(_image_depth[image->imgtype],
image->w, image->h);
image->dat = image->bmp->dat;
image->line = image->bmp->line;
return 0;
}
static int alleg_getpixel(const Image *image, int x, int y)
{
return getpixel(image->bmp, x, y);
}
static void alleg_putpixel(Image *image, int x, int y, int color)
{
putpixel(image->bmp, x, y, color);
}
static void alleg_clear(Image *image, int color)
{
clear_to_color(image->bmp, color);
}
static void alleg_copy(Image *dst, const Image *src, int x, int y)
{
blit(src->bmp, dst->bmp, 0, 0, x, y, src->w, src->h);
#if 0
ase_uint8 *src_address;
ase_uint8 *dst_address;
int xbeg, xend, xsrc;
int ybeg, yend, ysrc, ydst;
int bytes;
/* clipping */
xsrc = 0;
ysrc = 0;
xbeg = x;
ybeg = y;
xend = x+src->w-1;
yend = y+src->h-1;
if ((xend < 0) || (xbeg >= dst->w) ||
(yend < 0) || (ybeg >= dst->h))
return;
if (xbeg < 0) {
xsrc -= xbeg;
xbeg = 0;
}
if (ybeg < 0) {
ysrc -= ybeg;
ybeg = 0;
}
if (xend >= dst->w)
xend = dst->w-1;
if (yend >= dst->h)
yend = dst->h-1;
/* copy process */
bytes = (xend - xbeg + 1);
for (ydst=ybeg; ydst<=yend; ydst++, ysrc++) {
src_address = LINES (src)[ysrc]+xsrc;
dst_address = LINES (dst)[ydst]+xbeg;
memcpy (dst_address, src_address, bytes);
}
#endif
}
/* if "color_map" is not NULL, it's used by the routine to merge the
source and the destionation pixels */
static void alleg_merge(Image *dst, const Image *src,
int x, int y, int opacity, int blend_mode)
{
masked_blit(src->bmp, dst->bmp, 0, 0, x, y, src->w, src->h);
#if 0
ase_uint8 *src_address;
ase_uint8 *dst_address;
int xbeg, xend, xsrc, xdst;
int ybeg, yend, ysrc, ydst;
/* clipping */
xsrc = 0;
ysrc = 0;
xbeg = x;
ybeg = y;
xend = x+src->w-1;
yend = y+src->h-1;
if ((xend < 0) || (xbeg >= dst->w) ||
(yend < 0) || (ybeg >= dst->h))
return;
if (xbeg < 0) {
xsrc -= xbeg;
xbeg = 0;
}
if (ybeg < 0) {
ysrc -= ybeg;
ybeg = 0;
}
if (xend >= dst->w)
xend = dst->w-1;
if (yend >= dst->h)
yend = dst->h-1;
/* merge process */
/* direct copy */
if (blend_mode == BLEND_MODE_COPY) {
for (ydst=ybeg; ydst<=yend; ydst++, ysrc++) {
src_address = LINES (src)[ysrc]+xsrc;
dst_address = LINES (dst)[ydst]+xbeg;
for (xdst=xbeg; xdst<=xend; xdst++) {
*dst_address = (*src_address);
dst_address++;
src_address++;
}
}
}
/* with mask */
else {
for (ydst=ybeg; ydst<=yend; ydst++, ysrc++) {
src_address = LINES (src)[ysrc]+xsrc;
dst_address = LINES (dst)[ydst]+xbeg;
for (xdst=xbeg; xdst<=xend; xdst++) {
if (*src_address) {
if (color_map)
*dst_address = color_map->data[*src_address][*dst_address];
else
*dst_address = (*src_address);
}
dst_address++;
src_address++;
}
}
}
#endif
}
static void alleg_hline(Image *image, int x1, int y, int x2, int color)
{
hline(image->bmp, x1, y, x2, color);
}
static void alleg_rectfill(Image *image, int x1, int y1, int x2, int y2, int color)
{
rectfill(image->bmp, x1, y1, x2, y2, color);
}
static void alleg_to_allegro(const Image *image, BITMAP *bmp, int _x, int _y)
{
blit(image->bmp, bmp, 0, 0, _x, _y, image->w, image->h);
}
static ImageMethods alleg_methods =
{
alleg_init,
alleg_getpixel,
alleg_putpixel,
alleg_clear,
alleg_copy,
alleg_merge,
alleg_hline,
alleg_rectfill,
alleg_to_allegro,
};

View File

@ -1,395 +0,0 @@
/* 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
*/
#undef BYTES
#undef LINES
#define BYTES(image) ((ase_uint8 *)image->dat)
#define LINES(image) ((ase_uint8 **)image->line)
#define BITMAP_HLINE(op) \
for (x=x1; x<=x2; x++) { \
*address op (1<<d.rem); \
_image_bitmap_next_bit(d, address); \
}
static void bitmap_regenerate_lines(Image *image)
{
ase_uint8 *address = BYTES(image);
int y;
if (LINES(image))
delete[] LINES(image);
image->line = new ase_uint8*[image->h];
for (y=0; y<image->h; y++) {
LINES(image)[y] = address;
address += (image->w+7)/8;
}
}
static void bitmap_init(Image *image)
{
image->dat = new ase_uint8[((image->w+7)/8) * image->h];
try {
bitmap_regenerate_lines(image);
}
catch (...) {
delete[] BYTES(image);
throw;
}
}
static int bitmap_getpixel(const Image *image, int x, int y)
{
div_t d = div (x, 8);
return ((*(LINES (image)[y]+d.quot)) & (1<<d.rem)) ? 1: 0;
}
static void bitmap_putpixel(Image *image, int x, int y, int color)
{
div_t d = div (x, 8);
if (color)
*(LINES (image)[y]+d.quot) |= (1<<d.rem);
else
*(LINES (image)[y]+d.quot) &= ~(1<<d.rem);
}
static void bitmap_clear(Image *image, int color)
{
memset(BYTES(image), color ? 0xff: 0x00, ((image->w+7)/8) * image->h);
}
static void bitmap_copy(Image *dst, const Image *src, int x, int y)
{
ase_uint8 *src_address;
ase_uint8 *dst_address;
int xbeg, xend, xsrc, xdst;
int ybeg, yend, ysrc, ydst;
div_t src_d, src_beg_d;
div_t dst_d, dst_beg_d;
/* clipping */
xsrc = 0;
ysrc = 0;
xbeg = x;
ybeg = y;
xend = x+src->w-1;
yend = y+src->h-1;
if ((xend < 0) || (xbeg >= dst->w) ||
(yend < 0) || (ybeg >= dst->h))
return;
if (xbeg < 0) {
xsrc -= xbeg;
xbeg = 0;
}
if (ybeg < 0) {
ysrc -= ybeg;
ybeg = 0;
}
if (xend >= dst->w)
xend = dst->w-1;
if (yend >= dst->h)
yend = dst->h-1;
/* copy process */
src_beg_d = div (xsrc, 8);
dst_beg_d = div (xbeg, 8);
for (ydst=ybeg; ydst<=yend; ydst++, ysrc++) {
src_d = src_beg_d;
dst_d = dst_beg_d;
src_address = LINES (src)[ysrc]+src_d.quot;
dst_address = LINES (dst)[ydst]+dst_d.quot;
for (xdst=xbeg; xdst<=xend; xdst++) {
if ((*src_address & (1<<src_d.rem)))
*dst_address |= (1<<dst_d.rem);
else
*dst_address &= ~(1<<dst_d.rem);
_image_bitmap_next_bit (src_d, src_address);
_image_bitmap_next_bit (dst_d, dst_address);
}
}
}
static void bitmap_merge(Image *dst, const Image *src,
int x, int y, int opacity, int blend_mode)
{
ase_uint8 *src_address;
ase_uint8 *dst_address;
int xbeg, xend, xsrc, xdst;
int ybeg, yend, ysrc, ydst;
div_t src_d, src_beg_d;
div_t dst_d, dst_beg_d;
/* clipping */
xsrc = 0;
ysrc = 0;
xbeg = x;
ybeg = y;
xend = x+src->w-1;
yend = y+src->h-1;
if ((xend < 0) || (xbeg >= dst->w) ||
(yend < 0) || (ybeg >= dst->h))
return;
if (xbeg < 0) {
xsrc -= xbeg;
xbeg = 0;
}
if (ybeg < 0) {
ysrc -= ybeg;
ybeg = 0;
}
if (xend >= dst->w)
xend = dst->w-1;
if (yend >= dst->h)
yend = dst->h-1;
/* copy process */
src_beg_d = div (xsrc, 8);
dst_beg_d = div (xbeg, 8);
for (ydst=ybeg; ydst<=yend; ydst++, ysrc++) {
src_d = src_beg_d;
dst_d = dst_beg_d;
src_address = LINES (src)[ysrc]+src_d.quot;
dst_address = LINES (dst)[ydst]+dst_d.quot;
for (xdst=xbeg; xdst<=xend; xdst++) {
if ((*src_address & (1<<src_d.rem)))
*dst_address |= (1<<dst_d.rem);
_image_bitmap_next_bit (src_d, src_address);
_image_bitmap_next_bit (dst_d, dst_address);
}
}
}
static void bitmap_hline(Image *image, int x1, int y, int x2, int color)
{
ase_uint8 *address;
div_t d = div (x1, 8);
int x;
address = LINES (image)[y]+d.quot;
if (color) {
BITMAP_HLINE( |= );
}
else {
BITMAP_HLINE( &= ~ );
}
}
static void bitmap_rectfill(Image *image, int x1, int y1, int x2, int y2, int color)
{
ase_uint8 *address;
div_t d, beg_d = div (x1, 8);
int x, y;
if (color) {
for (y=y1; y<=y2; y++) {
d = beg_d;
address = LINES (image)[y]+d.quot;
BITMAP_HLINE( |= );
}
}
else {
for (y=y1; y<=y2; y++) {
d = beg_d;
address = LINES (image)[y]+d.quot;
BITMAP_HLINE( &= ~ );
}
}
}
static void bitmap_to_allegro(const Image *image, BITMAP *bmp, int _x, int _y)
{
ase_uint8 *address;
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<image->h; y++) {
address = LINES(image)[y];
bmp_address = (unsigned long)bmp->line[_y];
d = beg_d;
for (x=0; x<image->w; x++) {
outportw (0x3C4, (0x100<<((_x+x)&3))|2);
bmp_write8(bmp_address+((_x+x)>>2),
color[((*address) & (1<<d.rem))? 1: 0]);
_image_bitmap_next_bit(d, address);
}
_y++;
}
}
else {
#endif
for (y=0; y<image->h; y++) {
address = LINES (image)[y];
bmp_address = bmp_write_line(bmp, _y)+_x;
d = beg_d;
for (x=0; x<image->w; x++) {
bmp_write8 (bmp_address++, color[((*address) & (1<<d.rem))? 1: 0]);
_image_bitmap_next_bit(d, address);
}
_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<image->h; y++) {
address = LINES (image)[y];
bmp_address = bmp_write_line(bmp, _y)+_x;
d = beg_d;
for (x=0; x<image->w; x++) {
bmp_write15(bmp_address, color[((*address) & (1<<d.rem))? 1: 0]);
bmp_address += 2;
_image_bitmap_next_bit(d, address);
}
_y++;
}
break;
case 16:
color[0] = makecol16(0, 0, 0);
color[1] = makecol16(255, 255, 255);
_x <<= 1;
for (y=0; y<image->h; y++) {
address = LINES (image)[y];
bmp_address = bmp_write_line(bmp, _y)+_x;
d = beg_d;
for (x=0; x<image->w; x++) {
bmp_write16(bmp_address, color[((*address) & (1<<d.rem))? 1: 0]);
bmp_address += 2;
_image_bitmap_next_bit(d, address);
}
_y++;
}
break;
case 24:
color[0] = makecol24 (0, 0, 0);
color[1] = makecol24 (255, 255, 255);
_x *= 3;
for (y=0; y<image->h; y++) {
address = LINES (image)[y];
bmp_address = bmp_write_line(bmp, _y)+_x;
d = beg_d;
for (x=0; x<image->w; x++) {
bmp_write24(bmp_address, color[((*address) & (1<<d.rem))? 1: 0]);
bmp_address += 3;
_image_bitmap_next_bit (d, address);
}
_y++;
}
break;
case 32:
color[0] = makeacol32 (0, 0, 0, 255);
color[1] = makeacol32 (255, 255, 255, 255);
_x <<= 2;
for (y=0; y<image->h; y++) {
address = LINES (image)[y];
bmp_address = bmp_write_line (bmp, _y)+_x;
d = beg_d;
for (x=0; x<image->w; x++) {
bmp_write32 (bmp_address, color[((*address) & (1<<d.rem))? 1: 0]);
bmp_address += 4;
_image_bitmap_next_bit (d, address);
}
_y++;
}
break;
}
bmp_unwrite_line (bmp);
}
static ImageMethods bitmap_methods =
{
bitmap_init,
bitmap_getpixel,
bitmap_putpixel,
bitmap_clear,
bitmap_copy,
bitmap_merge,
bitmap_hline,
bitmap_rectfill,
bitmap_to_allegro,
};

View File

@ -1,337 +0,0 @@
/* 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
*/
#undef BYTES
#undef LINES
#define BYTES(image) ((ase_uint16 *)image->dat)
#define LINES(image) ((ase_uint16 **)image->line)
static void grayscale_regenerate_lines(Image *image)
{
ase_uint16 *address = BYTES(image);
int y;
if (LINES(image))
delete[] LINES(image);
image->line = (ase_uint8**)new ase_uint16*[image->h];
for (y=0; y<image->h; y++) {
LINES(image)[y] = address;
address += image->w;
}
}
static void grayscale_init(Image *image)
{
image->dat = (ase_uint8*)new ase_uint16[image->w * image->h];
try {
grayscale_regenerate_lines(image);
}
catch (...) {
delete[] BYTES(image);
throw;
}
}
static int grayscale_getpixel(const Image *image, int x, int y)
{
return *(LINES (image)[y]+x);
}
static void grayscale_putpixel (Image *image, int x, int y, int color)
{
*(LINES (image)[y]+x) = color;
}
static void grayscale_clear (Image *image, int color)
{
ase_uint16 *address = BYTES (image);
int c, size = image->w * image->h;
for (c=0; c<size; c++)
*(address++) = color;
}
static void grayscale_copy (Image *dst, const Image *src, int x, int y)
{
ase_uint16 *src_address;
ase_uint16 *dst_address;
int xbeg, xend, xsrc;
int ybeg, yend, ysrc, ydst;
int bytes;
/* clipping */
xsrc = 0;
ysrc = 0;
xbeg = x;
ybeg = y;
xend = x+src->w-1;
yend = y+src->h-1;
if ((xend < 0) || (xbeg >= dst->w) ||
(yend < 0) || (ybeg >= dst->h))
return;
if (xbeg < 0) {
xsrc -= xbeg;
xbeg = 0;
}
if (ybeg < 0) {
ysrc -= ybeg;
ybeg = 0;
}
if (xend >= dst->w)
xend = dst->w-1;
if (yend >= dst->h)
yend = dst->h-1;
/* copy process */
bytes = (xend - xbeg + 1) << 1;
for (ydst=ybeg; ydst<=yend; ydst++, ysrc++) {
src_address = LINES (src)[ysrc]+xsrc;
dst_address = LINES (dst)[ydst]+xbeg;
memcpy (dst_address, src_address, bytes);
}
}
static void grayscale_merge (Image *dst, const Image *src,
int x, int y, int opacity, int blend_mode)
{
BLEND_COLOR blender = _graya_blenders[blend_mode];
ase_uint16 *src_address;
ase_uint16 *dst_address;
int xbeg, xend, xsrc, xdst;
int ybeg, yend, ysrc, ydst;
/* nothing to do */
if (!opacity)
return;
/* clipping */
xsrc = 0;
ysrc = 0;
xbeg = x;
ybeg = y;
xend = x+src->w-1;
yend = y+src->h-1;
if ((xend < 0) || (xbeg >= dst->w) ||
(yend < 0) || (ybeg >= dst->h))
return;
if (xbeg < 0) {
xsrc -= xbeg;
xbeg = 0;
}
if (ybeg < 0) {
ysrc -= ybeg;
ybeg = 0;
}
if (xend >= dst->w)
xend = dst->w-1;
if (yend >= dst->h)
yend = dst->h-1;
/* merge process */
for (ydst=ybeg; ydst<=yend; ydst++, ysrc++) {
src_address = LINES (src)[ysrc]+xsrc;
dst_address = LINES (dst)[ydst]+xbeg;
for (xdst=xbeg; xdst<=xend; xdst++) {
*dst_address = (*blender) (*dst_address, *src_address, opacity);
dst_address++;
src_address++;
}
}
}
static void grayscale_hline (Image *image, int x1, int y, int x2, int color)
{
ase_uint16 *address = LINES (image)[y]+x1;
int x;
for (x=x1; x<=x2; x++)
*(address++) = color;
}
static void grayscale_rectfill (Image *image, int x1, int y1, int x2, int y2, int color)
{
ase_uint16 *address;
int x, y;
for (y=y1; y<=y2; y++) {
address = LINES (image)[y]+x1;
for (x=x1; x<=x2; x++)
*(address++) = color;
}
}
static void grayscale_to_allegro(const Image *image, BITMAP *bmp, int _x, int _y)
{
ase_uint16 *address = BYTES(image);
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<image->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),
_index_cmap[(*address) & 0xff]);
address++;
}
_y++;
}
}
else {
#endif
for (y=0; y<image->h; y++) {
bmp_address = bmp_write_line (bmp, _y)+_x;
for (x=0; x<image->w; x++) {
bmp_write8 (bmp_address, _index_cmap[(*address) & 0xff]);
address++;
bmp_address++;
}
_y++;
}
#if defined GFX_MODEX && !defined ALLEGRO_UNIX
}
#endif
break;
case 15:
_x <<= 1;
for (y=0; y<image->h; y++) {
bmp_address = bmp_write_line (bmp, _y)+_x;
for (x=0; x<image->w; x++) {
bmp_write15 (bmp_address,
makecol15 ((*address) & 0xff,
(*address) & 0xff,
(*address) & 0xff));
address++;
bmp_address += 2;
}
_y++;
}
break;
case 16:
_x <<= 1;
for (y=0; y<image->h; y++) {
bmp_address = bmp_write_line (bmp, _y)+_x;
for (x=0; x<image->w; x++) {
bmp_write16 (bmp_address,
makecol16 ((*address) & 0xff,
(*address) & 0xff,
(*address) & 0xff));
address++;
bmp_address += 2;
}
_y++;
}
break;
case 24:
_x *= 3;
for (y=0; y<image->h; y++) {
bmp_address = bmp_write_line(bmp, _y)+_x;
for (x=0; x<image->w; x++) {
bmp_write24(bmp_address,
makecol24((*address) & 0xff,
(*address) & 0xff,
(*address) & 0xff));
address++;
bmp_address += 3;
}
_y++;
}
break;
case 32:
_x <<= 2;
for (y=0; y<image->h; y++) {
bmp_address = bmp_write_line(bmp, _y)+_x;
for (x=0; x<image->w; x++) {
bmp_write32(bmp_address,
makeacol32((*address) & 0xff,
(*address) & 0xff,
(*address) & 0xff, 255));
address++;
bmp_address += 4;
}
_y++;
}
break;
}
bmp_unwrite_line (bmp);
}
static ImageMethods grayscale_methods =
{
grayscale_init,
grayscale_getpixel,
grayscale_putpixel,
grayscale_clear,
grayscale_copy,
grayscale_merge,
grayscale_hline,
grayscale_rectfill,
grayscale_to_allegro,
};

View File

@ -1,336 +0,0 @@
/* 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
*/
#undef BYTES
#undef LINES
#define BYTES(image) ((ase_uint8 *)image->dat)
#define LINES(image) ((ase_uint8 **)image->line)
static void indexed_regenerate_lines(Image *image)
{
ase_uint8 *address = BYTES(image);
int y;
if (LINES(image))
delete[] LINES(image);
image->line = new ase_uint8*[image->h];
for (y=0; y<image->h; y++) {
LINES(image)[y] = address;
address += image->w;
}
}
static void indexed_init(Image *image)
{
image->dat = new ase_uint8[image->w * image->h];
try {
indexed_regenerate_lines(image);
}
catch (...) {
delete[] BYTES(image);
throw;
}
}
static int indexed_getpixel(const Image *image, int x, int y)
{
return *(LINES(image)[y]+x);
}
static void indexed_putpixel(Image *image, int x, int y, int color)
{
*(LINES(image)[y]+x) = color;
}
static void indexed_clear(Image *image, int color)
{
memset(BYTES(image), color, image->w*image->h);
}
static void indexed_copy(Image *dst, const Image *src, int x, int y)
{
ase_uint8 *src_address;
ase_uint8 *dst_address;
int xbeg, xend, xsrc;
int ybeg, yend, ysrc, ydst;
int bytes;
/* clipping */
xsrc = 0;
ysrc = 0;
xbeg = x;
ybeg = y;
xend = x+src->w-1;
yend = y+src->h-1;
if ((xend < 0) || (xbeg >= dst->w) ||
(yend < 0) || (ybeg >= dst->h))
return;
if (xbeg < 0) {
xsrc -= xbeg;
xbeg = 0;
}
if (ybeg < 0) {
ysrc -= ybeg;
ybeg = 0;
}
if (xend >= dst->w)
xend = dst->w-1;
if (yend >= dst->h)
yend = dst->h-1;
/* copy process */
bytes = (xend - xbeg + 1);
for (ydst=ybeg; ydst<=yend; ydst++, ysrc++) {
src_address = LINES (src)[ysrc]+xsrc;
dst_address = LINES (dst)[ydst]+xbeg;
memcpy(dst_address, src_address, bytes);
}
}
/* if "color_map" is not NULL, it's used by the routine to merge the
source and the destionation pixels */
static void indexed_merge(Image *dst, const Image *src,
int x, int y, int opacity, int blend_mode)
{
ase_uint8 *src_address;
ase_uint8 *dst_address;
int xbeg, xend, xsrc, xdst;
int ybeg, yend, ysrc, ydst;
/* clipping */
xsrc = 0;
ysrc = 0;
xbeg = x;
ybeg = y;
xend = x+src->w-1;
yend = y+src->h-1;
if ((xend < 0) || (xbeg >= dst->w) ||
(yend < 0) || (ybeg >= dst->h))
return;
if (xbeg < 0) {
xsrc -= xbeg;
xbeg = 0;
}
if (ybeg < 0) {
ysrc -= ybeg;
ybeg = 0;
}
if (xend >= dst->w)
xend = dst->w-1;
if (yend >= dst->h)
yend = dst->h-1;
/* merge process */
/* direct copy */
if (blend_mode == BLEND_MODE_COPY) {
for (ydst=ybeg; ydst<=yend; ydst++, ysrc++) {
src_address = LINES (src)[ysrc]+xsrc;
dst_address = LINES (dst)[ydst]+xbeg;
for (xdst=xbeg; xdst<=xend; xdst++) {
*dst_address = (*src_address);
dst_address++;
src_address++;
}
}
}
/* with mask */
else {
for (ydst=ybeg; ydst<=yend; ydst++, ysrc++) {
src_address = LINES (src)[ysrc]+xsrc;
dst_address = LINES (dst)[ydst]+xbeg;
for (xdst=xbeg; xdst<=xend; xdst++) {
if (*src_address) {
if (color_map)
*dst_address = color_map->data[*src_address][*dst_address];
else
*dst_address = (*src_address);
}
dst_address++;
src_address++;
}
}
}
}
static void indexed_hline(Image *image, int x1, int y, int x2, int color)
{
memset(LINES(image)[y]+x1, color, x2-x1+1);
}
static void indexed_rectfill(Image *image, int x1, int y1, int x2, int y2, int color)
{
int y, bytes = x2-x1+1;
for (y=y1; y<=y2; y++)
memset(LINES(image)[y]+x1, color, bytes);
}
static void indexed_to_allegro(const Image *image, BITMAP *bmp, int _x, int _y)
{
#define RGB_TRIPLET \
_rgb_scale_6[_current_palette[_index_cmap[(*address)]].r], \
_rgb_scale_6[_current_palette[_index_cmap[(*address)]].g], \
_rgb_scale_6[_current_palette[_index_cmap[(*address)]].b]
ase_uint8 *address = BYTES(image);
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<image->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), _index_cmap[(*address)]);
address++;
}
_y++;
}
}
else {
#endif
for (y=0; y<image->h; y++) {
bmp_address = bmp_write_line(bmp, _y)+_x;
for (x=0; x<image->w; x++) {
bmp_write8(bmp_address, _index_cmap[(*address)]);
address++;
bmp_address++;
}
_y++;
}
#if defined GFX_MODEX && !defined ALLEGRO_UNIX
}
#endif
break;
case 15:
_x <<= 1;
for (y=0; y<image->h; y++) {
bmp_address = bmp_write_line(bmp, _y)+_x;
for (x=0; x<image->w; x++) {
bmp_write15(bmp_address, makecol15(RGB_TRIPLET));
address++;
bmp_address += 2;
}
_y++;
}
break;
case 16:
_x <<= 1;
for (y=0; y<image->h; y++) {
bmp_address = bmp_write_line(bmp, _y)+_x;
for (x=0; x<image->w; x++) {
bmp_write16(bmp_address, makecol16(RGB_TRIPLET));
address++;
bmp_address += 2;
}
_y++;
}
break;
case 24:
_x *= 3;
for (y=0; y<image->h; y++) {
bmp_address = bmp_write_line(bmp, _y)+_x;
for (x=0; x<image->w; x++) {
bmp_write24(bmp_address, makecol24(RGB_TRIPLET));
address++;
bmp_address += 3;
}
_y++;
}
break;
case 32:
_x <<= 2;
for (y=0; y<image->h; y++) {
bmp_address = bmp_write_line(bmp, _y)+_x;
for (x=0; x<image->w; x++) {
bmp_write32(bmp_address, makeacol32(RGB_TRIPLET, 255));
address++;
bmp_address += 4;
}
_y++;
}
break;
}
bmp_unwrite_line(bmp);
}
static ImageMethods indexed_methods =
{
indexed_init,
indexed_getpixel,
indexed_putpixel,
indexed_clear,
indexed_copy,
indexed_merge,
indexed_hline,
indexed_rectfill,
indexed_to_allegro,
};

View File

@ -1,343 +0,0 @@
/* 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
*/
#undef BYTES
#undef LINES
#define BYTES(image) ((ase_uint32 *)image->dat)
#define LINES(image) ((ase_uint32 **)image->line)
static void rgb_regenerate_lines(Image *image)
{
ase_uint32 *address = BYTES(image);
int y;
if (LINES(image))
delete[] LINES(image);
image->line = (ase_uint8**)new ase_uint32*[image->h];
for (y=0; y<image->h; y++) {
LINES(image)[y] = address;
address += image->w;
}
}
static void rgb_init(Image *image)
{
image->dat = (ase_uint8*)new ase_uint32[image->w * image->h];
try {
rgb_regenerate_lines(image);
}
catch (...) {
delete[] BYTES(image);
throw;
}
}
static int rgb_getpixel(const Image *image, int x, int y)
{
return *(LINES(image)[y]+x);
}
static void rgb_putpixel(Image *image, int x, int y, int color)
{
*(LINES(image)[y]+x) = color;
}
static void rgb_clear(Image *image, int color)
{
ase_uint32 *address = BYTES(image);
unsigned int c, size = image->w * image->h;
for (c=0; c<size; c++)
*(address++) = color;
}
static void rgb_copy(Image *dst, const Image *src, int x, int y)
{
ase_uint32 *src_address;
ase_uint32 *dst_address;
int xbeg, xend, xsrc;
int ybeg, yend, ysrc, ydst;
int bytes;
/* clipping */
xsrc = 0;
ysrc = 0;
xbeg = x;
ybeg = y;
xend = x+src->w-1;
yend = y+src->h-1;
if ((xend < 0) || (xbeg >= dst->w) ||
(yend < 0) || (ybeg >= dst->h))
return;
if (xbeg < 0) {
xsrc -= xbeg;
xbeg = 0;
}
if (ybeg < 0) {
ysrc -= ybeg;
ybeg = 0;
}
if (xend >= dst->w)
xend = dst->w-1;
if (yend >= dst->h)
yend = dst->h-1;
/* copy process */
bytes = (xend - xbeg + 1) << 2;
for (ydst=ybeg; ydst<=yend; ydst++, ysrc++) {
src_address = LINES(src)[ysrc]+xsrc;
dst_address = LINES(dst)[ydst]+xbeg;
memcpy(dst_address, src_address, bytes);
}
}
static void rgb_merge(Image *dst, const Image *src,
int x, int y, int opacity, int blend_mode)
{
BLEND_COLOR blender = _rgba_blenders[blend_mode];
ase_uint32 *src_address;
ase_uint32 *dst_address;
int xbeg, xend, xsrc, xdst;
int ybeg, yend, ysrc, ydst;
/* nothing to do */
if (!opacity)
return;
/* clipping */
xsrc = 0;
ysrc = 0;
xbeg = x;
ybeg = y;
xend = x+src->w-1;
yend = y+src->h-1;
if ((xend < 0) || (xbeg >= dst->w) ||
(yend < 0) || (ybeg >= dst->h))
return;
if (xbeg < 0) {
xsrc -= xbeg;
xbeg = 0;
}
if (ybeg < 0) {
ysrc -= ybeg;
ybeg = 0;
}
if (xend >= dst->w)
xend = dst->w-1;
if (yend >= dst->h)
yend = dst->h-1;
/* merge process */
for (ydst=ybeg; ydst<=yend; ydst++, ysrc++) {
src_address = LINES(src)[ysrc]+xsrc;
dst_address = LINES(dst)[ydst]+xbeg;
for (xdst=xbeg; xdst<=xend; xdst++) {
*dst_address = (*blender)(*dst_address, *src_address, opacity);
dst_address++;
src_address++;
}
}
}
static void rgb_hline(Image *image, int x1, int y, int x2, int color)
{
ase_uint32 *address = LINES(image)[y]+x1;
int x;
for (x=x1; x<=x2; x++)
*(address++) = color;
}
static void rgb_rectfill(Image *image, int x1, int y1, int x2, int y2, int color)
{
ase_uint32 *address;
int x, y;
for (y=y1; y<=y2; y++) {
address = LINES(image)[y]+x1;
for (x=x1; x<=x2; x++)
*(address++) = color;
}
}
static void rgb_to_allegro(const Image *image, BITMAP *bmp, int _x, int _y)
{
ase_uint32 *address = BYTES(image);
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<image->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((*address) & 0xff,
((*address)>>8) & 0xff,
((*address)>>16) & 0xff));
address++;
}
_y++;
}
}
else {
#endif
for (y=0; y<image->h; y++) {
bmp_address = bmp_write_line(bmp, _y)+_x;
for (x=0; x<image->w; x++) {
bmp_write8(bmp_address,
makecol8((*address) & 0xff,
((*address)>>8) & 0xff,
((*address)>>16) & 0xff));
address++;
bmp_address++;
}
_y++;
}
#if defined GFX_MODEX && !defined ALLEGRO_UNIX
}
#endif
break;
case 15:
_x <<= 1;
for (y=0; y<image->h; y++) {
bmp_address = bmp_write_line(bmp, _y)+_x;
for (x=0; x<image->w; x++) {
bmp_write15(bmp_address,
makecol15((*address) & 0xff,
((*address)>>8) & 0xff,
((*address)>>16) & 0xff));
address++;
bmp_address += 2;
}
_y++;
}
break;
case 16:
_x <<= 1;
for (y=0; y<image->h; y++) {
bmp_address = bmp_write_line (bmp, _y)+_x;
for (x=0; x<image->w; x++) {
bmp_write16(bmp_address,
makecol16((*address) & 0xff,
((*address)>>8) & 0xff,
((*address)>>16) & 0xff));
address++;
bmp_address += 2;
}
_y++;
}
break;
case 24:
_x *= 3;
for (y=0; y<image->h; y++) {
bmp_address = bmp_write_line (bmp, _y)+_x;
for (x=0; x<image->w; x++) {
bmp_write24(bmp_address,
makecol24((*address) & 0xff,
((*address)>>8) & 0xff,
((*address)>>16) & 0xff));
address++;
bmp_address += 3;
}
_y++;
}
break;
case 32:
_x <<= 2;
for (y=0; y<image->h; y++) {
bmp_address = bmp_write_line (bmp, _y)+_x;
for (x=0; x<image->w; x++) {
bmp_write32(bmp_address,
makeacol32((*address) & 0xff,
((*address)>>8) & 0xff,
((*address)>>16) & 0xff,
((*address)>>24) & 0xff));
address++;
bmp_address += 4;
}
_y++;
}
break;
}
bmp_unwrite_line(bmp);
}
static ImageMethods rgb_methods =
{
rgb_init,
rgb_getpixel,
rgb_putpixel,
rgb_clear,
rgb_copy,
rgb_merge,
rgb_hline,
rgb_rectfill,
rgb_to_allegro,
};

View File

@ -379,6 +379,20 @@ void layer_set_blend_mode(Layer* layer, int blend_mode)
layer->blend_mode = blend_mode; layer->blend_mode = blend_mode;
} }
void layer_get_cels(const Layer* layer, JList cels)
{
JLink link;
if (layer_is_image(layer)) {
JI_LIST_FOR_EACH(layer->cels, link)
jlist_append(cels, link->data);
}
else if (layer_is_set(layer)) {
JI_LIST_FOR_EACH(layer->layers, link)
layer_get_cels((const Layer*)link->data, cels);
}
}
void layer_add_cel(Layer* layer, Cel* cel) void layer_add_cel(Layer* layer, Cel* cel)
{ {
if (layer_is_image(layer)) { if (layer_is_image(layer)) {

View File

@ -74,6 +74,7 @@ Layer* layer_get_next(Layer* layer);
void layer_set_name(Layer* layer, const char *name); void layer_set_name(Layer* layer, const char *name);
void layer_set_blend_mode(Layer* layer, int blend_mode); void layer_set_blend_mode(Layer* layer, int blend_mode);
void layer_get_cels(const Layer* layer, JList cels);
/* for LAYER_IMAGE */ /* for LAYER_IMAGE */
void layer_add_cel(Layer* layer, Cel *cel); void layer_add_cel(Layer* layer, Cel *cel);

View File

@ -430,7 +430,7 @@ static void shrink_mask(Mask* mask)
{ \ { \
for (u = u_begin; u u_op u_final; u u_add) { \ for (u = u_begin; u u_op u_final; u u_add) { \
for (v = v_begin; v v_op v_final; v v_add) { \ for (v = v_begin; v v_op v_final; v v_add) { \
if (mask->bitmap->method->getpixel(mask->bitmap, U, V)) \ if (mask->bitmap->getpixel(U, V)) \
break; \ break; \
} \ } \
if (v == v_final) \ if (v == v_final) \

View File

@ -213,7 +213,7 @@ Image *image_rgb_to_indexed(Image *src_image,
for (y=0; y<src_image->h; y++) { for (y=0; y<src_image->h; y++) {
for (x=0; x<src_image->w; x++) { for (x=0; x<src_image->w; x++) {
c = src_image->method->getpixel(src_image, x, y); c = image_getpixel_fast<RgbTraits>(src_image, x, y);
r = _rgba_getr(c); r = _rgba_getr(c);
g = _rgba_getg(c); g = _rgba_getg(c);
@ -258,7 +258,7 @@ Image *image_rgb_to_indexed(Image *src_image,
else else
nearestcm = 0; nearestcm = 0;
dst_image->method->putpixel(dst_image, x, y, nearestcm); image_putpixel_fast<IndexedTraits>(dst_image, x, y, nearestcm);
} }
} }

View File

@ -724,6 +724,11 @@ int sprite_count_layers(const Sprite* sprite)
return layer_count_layers(sprite->set)-1; return layer_count_layers(sprite->set)-1;
} }
void sprite_get_cels(Sprite* sprite, JList cels)
{
return layer_get_cels(sprite->set, cels);
}
/** /**
* Gets a pixel from the sprite in the specified position. If in the * Gets a pixel from the sprite in the specified position. If in the
* specified coordinates there're background this routine will return * specified coordinates there're background this routine will return
@ -754,7 +759,7 @@ int sprite_get_memsize(Sprite* sprite)
image = sprite->stock->image[i]; image = sprite->stock->image[i];
if (image != NULL) if (image != NULL)
size += IMAGE_LINE_SIZE(image, image->w) * image->h; size += image_line_size(image, image->w) * image->h;
} }
return size; return size;

View File

@ -137,6 +137,7 @@ void sprite_generate_mask_boundaries(Sprite* sprite);
Layer* sprite_index2layer(Sprite* sprite, int index); Layer* sprite_index2layer(Sprite* sprite, int index);
int sprite_layer2index(const Sprite* sprite, const Layer* layer); int sprite_layer2index(const Sprite* sprite, const Layer* layer);
int sprite_count_layers(const Sprite* sprite); int sprite_count_layers(const Sprite* sprite);
void sprite_get_cels(Sprite* sprite, JList cels);
int sprite_getpixel(Sprite* sprite, int x, int y); int sprite_getpixel(Sprite* sprite, int x, int y);

View File

@ -128,9 +128,10 @@ void stock_remove_image(Stock* stock, Image* image)
* Replaces the image in the stock in the "index" position with the * Replaces the image in the stock in the "index" position with the
* new "image"; you must free the old image before, e.g: * new "image"; you must free the old image before, e.g:
* @code * @code
* Image* old_image = stock_get_image (stock, index); * Image* old_image = stock_get_image(stock, index);
* if (old_image) image_free (old_image); * if (old_image)
* stock_replace_image (stock, index, new_image); * image_free(old_image);
* stock_replace_image(stock, index, new_image);
* @endcode * @endcode
*/ */
void stock_replace_image(Stock* stock, int index, Image* image) void stock_replace_image(Stock* stock, int index, Image* image)

View File

@ -614,7 +614,7 @@ static void chunk_image_new(UndoStream* stream, Image* image, int x, int y, int
assert(w >= 1 && h >= 1); assert(w >= 1 && h >= 1);
assert(x >= 0 && y >= 0 && x+w <= image->w && y+h <= image->h); assert(x >= 0 && y >= 0 && x+w <= image->w && y+h <= image->h);
size = IMAGE_LINE_SIZE(image, w); size = image_line_size(image, w);
chunk = (UndoChunkImage* ) chunk = (UndoChunkImage* )
undo_chunk_new(stream, undo_chunk_new(stream,
@ -630,7 +630,7 @@ static void chunk_image_new(UndoStream* stream, Image* image, int x, int y, int
ptr = chunk->data; ptr = chunk->data;
for (v=0; v<h; ++v) { for (v=0; v<h; ++v) {
memcpy(ptr, IMAGE_ADDRESS(image, x, y+v), size); memcpy(ptr, image_address(image, x, y+v), size);
ptr += size; ptr += size;
} }
} }
@ -656,11 +656,11 @@ static void chunk_image_invert(UndoStream* stream, UndoChunkImage* chunk, int st
chunk_image_new(stream, image, x, y, w, h); chunk_image_new(stream, image, x, y, w, h);
/* restore the old image portion */ /* restore the old image portion */
size = IMAGE_LINE_SIZE(image, chunk->w); size = image_line_size(image, chunk->w);
ptr = chunk->data; ptr = chunk->data;
for (v=0; v<h; ++v) { for (v=0; v<h; ++v) {
memcpy(IMAGE_ADDRESS(image, x, y+v), ptr, size); memcpy(image_address(image, x, y+v), ptr, size);
ptr += size; ptr += size;
} }
} }
@ -1537,11 +1537,11 @@ static Dirty *read_raw_dirty(ase_uint8* raw_data)
x = dirty->row[v].col[u].x; x = dirty->row[v].col[u].x;
size = IMAGE_LINE_SIZE(dirty->image, dirty->row[v].col[u].w); size = image_line_size(dirty->image, dirty->row[v].col[u].w);
dirty->row[v].col[u].flags = DIRTY_VALID_COLUMN; dirty->row[v].col[u].flags = DIRTY_VALID_COLUMN;
dirty->row[v].col[u].data = jmalloc(size); dirty->row[v].col[u].data = jmalloc(size);
dirty->row[v].col[u].ptr = IMAGE_ADDRESS(dirty->image, x, y); dirty->row[v].col[u].ptr = image_address(dirty->image, x, y);
read_raw_data(dirty->row[v].col[u].data, size); read_raw_data(dirty->row[v].col[u].data, size);
} }
@ -1574,7 +1574,7 @@ static ase_uint8* write_raw_dirty(ase_uint8* raw_data, Dirty *dirty)
write_raw_uint16(dirty->row[v].col[u].x); write_raw_uint16(dirty->row[v].col[u].x);
write_raw_uint16(dirty->row[v].col[u].w); write_raw_uint16(dirty->row[v].col[u].w);
size = IMAGE_LINE_SIZE(dirty->image, dirty->row[v].col[u].w); size = image_line_size(dirty->image, dirty->row[v].col[u].w);
write_raw_data(dirty->row[v].col[u].data, size); write_raw_data(dirty->row[v].col[u].data, size);
} }
} }
@ -1590,7 +1590,7 @@ static int get_raw_dirty_size(Dirty *dirty)
size += 4; /* y, cols (WORD[2]) */ size += 4; /* y, cols (WORD[2]) */
for (u=0; u<dirty->row[v].cols; u++) { for (u=0; u<dirty->row[v].cols; u++) {
size += 4; /* x, w (WORD[2]) */ size += 4; /* x, w (WORD[2]) */
size += IMAGE_LINE_SIZE(dirty->image, dirty->row[v].col[u].w); size += image_line_size(dirty->image, dirty->row[v].col[u].w);
} }
} }
@ -1632,7 +1632,7 @@ static Image* read_raw_image(ase_uint8* raw_data)
read_raw_uint16(height); /* height */ read_raw_uint16(height); /* height */
image = image_new(imgtype, width, height); image = image_new(imgtype, width, height);
size = IMAGE_LINE_SIZE(image, image->w); size = image_line_size(image, image->w);
for (c=0; c<image->h; c++) for (c=0; c<image->h; c++)
read_raw_data(image->line[c], size); read_raw_data(image->line[c], size);
@ -1652,7 +1652,7 @@ static ase_uint8* write_raw_image(ase_uint8* raw_data, Image* image)
write_raw_uint16(image->w); /* width */ write_raw_uint16(image->w); /* width */
write_raw_uint16(image->h); /* height */ write_raw_uint16(image->h); /* height */
size = IMAGE_LINE_SIZE(image, image->w); size = image_line_size(image, image->w);
for (c=0; c<image->h; c++) for (c=0; c<image->h; c++)
write_raw_data(image->line[c], size); write_raw_data(image->line[c], size);
@ -1662,7 +1662,7 @@ static ase_uint8* write_raw_image(ase_uint8* raw_data, Image* image)
static int get_raw_image_size(Image* image) static int get_raw_image_size(Image* image)
{ {
assert(image != NULL); assert(image != NULL);
return 4+1+2+2+IMAGE_LINE_SIZE(image, image->w) * image->h; return 4+1+2+2+image_line_size(image, image->w) * image->h;
} }
/*********************************************************************** /***********************************************************************

View File

@ -353,7 +353,7 @@ void Undoable::background_from_layer(Layer* layer, int bgcolor)
// create a temporary image to draw each frame of the new // create a temporary image to draw each frame of the new
// `Background' layer // `Background' layer
std::auto_ptr<Image> bg_image(new Image(sprite->imgtype, sprite->w, sprite->h)); std::auto_ptr<Image> bg_image(image_new(sprite->imgtype, sprite->w, sprite->h));
JLink link; JLink link;
JI_LIST_FOR_EACH(layer->cels, link) { JI_LIST_FOR_EACH(layer->cels, link) {

View File

@ -32,7 +32,7 @@ bool get_shrink_rect(int *x1, int *y1, int *x2, int *y2,
do { \ do { \
for (u = u_begin; u u_op u_final; u u_add) { \ for (u = u_begin; u u_op u_final; u u_add) { \
for (v = v_begin; v v_op v_final; v v_add) { \ for (v = v_begin; v v_op v_final; v v_add) { \
if (image->method->getpixel (image, U, V) != refpixel) \ if (image->getpixel(U, V) != refpixel) \
break; \ break; \
} \ } \
if (v == v_final) \ if (v == v_final) \
@ -77,8 +77,7 @@ bool get_shrink_rect2(int *x1, int *y1, int *x2, int *y2,
do { \ do { \
for (u = u_begin; u u_op u_final; u u_add) { \ for (u = u_begin; u u_op u_final; u u_add) { \
for (v = v_begin; v v_op v_final; v v_add) { \ for (v = v_begin; v v_op v_final; v v_add) { \
if (image->method->getpixel (image, U, V) != \ if (image->getpixel(U, V) != refimage->getpixel(U, V)) \
refimage->method->getpixel (refimage, U, V)) \
break; \ break; \
} \ } \
if (v == v_final) \ if (v == v_final) \

View File

@ -47,6 +47,8 @@
#include "widgets/colbar.h" #include "widgets/colbar.h"
#include "widgets/statebar.h" #include "widgets/statebar.h"
static ase_uint32 get_shift_from_mask(ase_uint32 mask);
#if defined ALLEGRO_WINDOWS #if defined ALLEGRO_WINDOWS
#include <winalleg.h> #include <winalleg.h>
#include "util/clipboard_win32.h" #include "util/clipboard_win32.h"
@ -79,7 +81,6 @@ enum {
static void destroy_clipboard(void* data); static void destroy_clipboard(void* data);
static void set_clipboard(Image* image, Palette* palette, bool set_system_clipboard); static void set_clipboard(Image* image, Palette* palette, bool set_system_clipboard);
static bool copy_from_sprite(Sprite* sprite); static bool copy_from_sprite(Sprite* sprite);
static ase_uint32 get_shift_from_mask(ase_uint32 mask);
static bool interactive_transform(JWidget widget, Image *dest_image, Image *image, static bool interactive_transform(JWidget widget, Image *dest_image, Image *image,
int x, int y, int xout[4], int yout[4]); int x, int y, int xout[4], int yout[4]);
@ -229,7 +230,7 @@ void clipboard::paste(Sprite* sprite)
clipboard_image->h); clipboard_image->h);
use_current_sprite_rgb_map(); use_current_sprite_rgb_map();
image_convert(src_image, clipboard_image); image_convert(clipboard_image, src_image);
restore_rgb_map(); restore_rgb_map();
} }
@ -353,7 +354,7 @@ static bool interactive_transform(JWidget widget,
int x, y; int x, y;
for (y=0; y<image->h; y++) for (y=0; y<image->h; y++)
for (x=0; x<image->w; x++) for (x=0; x<image->w; x++)
if (_rgba_geta(image->method->getpixel(image, x, y)) < 128) if (_rgba_geta(image_getpixel_fast<RgbTraits>(image, x, y)) < 128)
putpixel(preview, x, y, mask_color); putpixel(preview, x, y, mask_color);
break; break;
} }
@ -362,7 +363,7 @@ static bool interactive_transform(JWidget widget,
int x, y; int x, y;
for (y=0; y<image->h; y++) for (y=0; y<image->h; y++)
for (x=0; x<image->w; x++) for (x=0; x<image->w; x++)
if (_graya_geta(image->method->getpixel(image, x, y)) < 128) if (_graya_geta(image_getpixel_fast<GrayscaleTraits>(image, x, y)) < 128)
putpixel(preview, x, y, mask_color); putpixel(preview, x, y, mask_color);
break; break;
} }
@ -371,7 +372,7 @@ static bool interactive_transform(JWidget widget,
int x, y; int x, y;
for (y=0; y<image->h; y++) for (y=0; y<image->h; y++)
for (x=0; x<image->w; x++) for (x=0; x<image->w; x++)
if (image->method->getpixel(image, x, y) == 0) if (image_getpixel_fast<IndexedTraits>(image, x, y) == 0)
putpixel(preview, x, y, mask_color); putpixel(preview, x, y, mask_color);
break; break;
} }

View File

@ -104,7 +104,7 @@ static void set_win32_clipboard_bitmap(Image* image, Palette* palette)
ase_uint32 c; ase_uint32 c;
for (int y=image->h-1; y>=0; --y) for (int y=image->h-1; y>=0; --y)
for (int x=0; x<image->w; ++x) { for (int x=0; x<image->w; ++x) {
c = image->method->getpixel(image, x, y); c = image_getpixel_fast<RgbTraits>(image, x, y);
*(dst++) = ((_rgba_getb(c) << 0) | *(dst++) = ((_rgba_getb(c) << 0) |
(_rgba_getg(c) << 8) | (_rgba_getg(c) << 8) |
(_rgba_getr(c) << 16) | (_rgba_getr(c) << 16) |
@ -117,7 +117,7 @@ static void set_win32_clipboard_bitmap(Image* image, Palette* palette)
ase_uint16 c; ase_uint16 c;
for (int y=image->h-1; y>=0; --y) for (int y=image->h-1; y>=0; --y)
for (int x=0; x<image->w; ++x) { for (int x=0; x<image->w; ++x) {
c = image->method->getpixel(image, x, y); c = image_getpixel_fast<GrayscaleTraits>(image, x, y);
*(dst++) = ((_graya_getv(c) << 0) | *(dst++) = ((_graya_getv(c) << 0) |
(_graya_getv(c) << 8) | (_graya_getv(c) << 8) |
(_graya_getv(c) << 16) | (_graya_getv(c) << 16) |
@ -139,7 +139,7 @@ static void set_win32_clipboard_bitmap(Image* image, Palette* palette)
+ palette_entries*sizeof(RGBQUAD)); + palette_entries*sizeof(RGBQUAD));
for (int y=image->h-1; y>=0; --y) { for (int y=image->h-1; y>=0; --y) {
for (int x=0; x<image->w; ++x) { for (int x=0; x<image->w; ++x) {
*(dst++) = image->method->getpixel(image, x, y); *(dst++) = image_getpixel_fast<IndexedTraits>(image, x, y);
} }
dst += padding; dst += padding;
} }
@ -169,7 +169,13 @@ static void get_win32_clipboard_bitmap(Image*& image, Palette*& palette)
return; return;
BITMAPINFO* bi = (BITMAPINFO*)GetClipboardData(CF_DIB); BITMAPINFO* bi = (BITMAPINFO*)GetClipboardData(CF_DIB);
if (bi && bi->bmiHeader.biCompression == BI_RGB) { if (bi) {
if (bi->bmiHeader.biCompression != BI_RGB &&
bi->bmiHeader.biCompression != BI_BITFIELDS) {
jalert("Error<<The current Windows clipboard format is not a bitmap.||&OK");
return;
}
try { try {
image = image_new(bi->bmiHeader.biBitCount == 8 ? IMAGE_INDEXED: image = image_new(bi->bmiHeader.biBitCount == 8 ? IMAGE_INDEXED:
IMAGE_RGB, IMAGE_RGB,
@ -178,51 +184,72 @@ static void get_win32_clipboard_bitmap(Image*& image, Palette*& palette)
bool valid_image = false; bool valid_image = false;
switch (bi->bmiHeader.biBitCount) { switch (bi->bmiHeader.biBitCount) {
case 32: {
// BITMAPV5HEADER* bv5 = (BITMAPV5HEADER*)GetClipboardData(CF_DIBV5);
// ase_uint32* src = (ase_uint32*)(((ase_uint8*)bv5)+bv5->bV5Size);
ase_uint32* src = (ase_uint32*)(((ase_uint8*)bi)+bi->bmiHeader.biSize);
ase_uint32 c;
// int r_shift = get_shift_from_mask(bv5->bV5RedMask);
// int g_shift = get_shift_from_mask(bv5->bV5GreenMask);
// int b_shift = get_shift_from_mask(bv5->bV5BlueMask);
// int a_shift = get_shift_from_mask(bv5->bV5AlphaMask);
for (int y=image->h-1; y>=0; --y) { // 32 BPP
for (int x=0; x<image->w; ++x) { case 32:
c = *(src++); if (bi->bmiHeader.biCompression == BI_BITFIELDS) {
// image->method->putpixel(image, x, y, ase_uint32* src = (ase_uint32*)(((ase_uint8*)bi)+bi->bmiHeader.biSize+sizeof(RGBQUAD)*3);
// _rgba((c & bv5->bV5RedMask) >> r_shift, ase_uint32 c;
// (c & bv5->bV5GreenMask) >> g_shift,
// (c & bv5->bV5BlueMask) >> b_shift, ase_uint32 r_mask = (ase_uint32)*((ase_uint32*)&bi->bmiColors[0]);
// (c & bv5->bV5AlphaMask) >> a_shift)); ase_uint32 g_mask = (ase_uint32)*((ase_uint32*)&bi->bmiColors[1]);
image->method->putpixel(image, x, y, ase_uint32 b_mask = (ase_uint32)*((ase_uint32*)&bi->bmiColors[2]);
_rgba((c & 0x00ff0000) >> 16, ase_uint32 r_shift = get_shift_from_mask(r_mask);
(c & 0x0000ff00) >> 8, ase_uint32 g_shift = get_shift_from_mask(g_mask);
(c & 0x000000ff) >> 0, ase_uint32 b_shift = get_shift_from_mask(b_mask);
(c & 0xff000000) >> 24));
for (int y=image->h-1; y>=0; --y) {
ase_uint32* dst = (ase_uint32*)image->line[y];
for (int x=0; x<image->w; ++x) {
c = *(src++);
*(dst++) = _rgba((c & r_mask) >> r_shift,
(c & g_mask) >> g_shift,
(c & b_mask) >> b_shift, 255);
}
}
}
else if (bi->bmiHeader.biCompression == BI_RGB) {
ase_uint32* src = (ase_uint32*)(((ase_uint8*)bi)+bi->bmiHeader.biSize);
ase_uint32 c;
for (int y=image->h-1; y>=0; --y) {
ase_uint32* dst = (ase_uint32*)image->line[y];
for (int x=0; x<image->w; ++x) {
c = *(src++);
*(dst++) = _rgba((c & 0x00ff0000) >> 16,
(c & 0x0000ff00) >> 8,
(c & 0x000000ff) >> 0,
(c & 0xff000000) >> 24);
}
} }
} }
valid_image = true; valid_image = true;
break; break;
}
// 24 BPP
case 24: { case 24: {
ase_uint8* src = (((ase_uint8*)bi)+bi->bmiHeader.biSize); ase_uint8* src = (((ase_uint8*)bi)+bi->bmiHeader.biSize);
ase_uint8 r, g, b; ase_uint8 r, g, b;
int padding = (4-(image->w*3)&3)&3; int padding = (4-(image->w*3)&3)&3;
for (int y=image->h-1; y>=0; --y) { for (int y=image->h-1; y>=0; --y) {
ase_uint32* dst = (ase_uint32*)image->line[y];
for (int x=0; x<image->w; ++x) { for (int x=0; x<image->w; ++x) {
b = *(src++); b = *(src++);
g = *(src++); g = *(src++);
r = *(src++); r = *(src++);
image->method->putpixel(image, x, y, _rgba(r, g, b, 255)); *(dst++) = _rgba(r, g, b, 255);
} }
src += padding; src += padding;
} }
valid_image = true; valid_image = true;
break; break;
} }
// 16 BPP
case 16: { case 16: {
// TODO I am not sure if this really works // TODO I am not sure if this really works
ase_uint8* src = (((ase_uint8*)bi)+bi->bmiHeader.biSize); ase_uint8* src = (((ase_uint8*)bi)+bi->bmiHeader.biSize);
@ -236,13 +263,15 @@ static void get_win32_clipboard_bitmap(Image*& image, Palette*& palette)
b = _rgb_scale_5[((b1 & 0xf800) >> 11)]; b = _rgb_scale_5[((b1 & 0xf800) >> 11)];
g = _rgb_scale_6[((b2 & 0x07e0) >> 5)]; g = _rgb_scale_6[((b2 & 0x07e0) >> 5)];
r = _rgb_scale_5[(b2 & 0x001f)]; r = _rgb_scale_5[(b2 & 0x001f)];
image->method->putpixel(image, x, y, _rgba(r, g, b, 255)); image_putpixel_fast<RgbTraits>(image, x, y, _rgba(r, g, b, 255));
} }
src += padding; src += padding;
} }
valid_image = true; valid_image = true;
break; break;
} }
// 8 BPP
case 8: { case 8: {
int colors = bi->bmiHeader.biClrUsed > 0 ? bi->bmiHeader.biClrUsed: 256; int colors = bi->bmiHeader.biClrUsed > 0 ? bi->bmiHeader.biClrUsed: 256;
palette = palette_new(0, 256); palette = palette_new(0, 256);
@ -263,7 +292,7 @@ static void get_win32_clipboard_bitmap(Image*& image, Palette*& palette)
for (int y=image->h-1; y>=0; --y) { for (int y=image->h-1; y>=0; --y) {
for (int x=0; x<image->w; ++x) for (int x=0; x<image->w; ++x)
image->method->putpixel(image, x, y, *(src++) & 0xff); image_putpixel_fast<IndexedTraits>(image, x, y, *(src++) & 0xff);
src += padding; src += padding;
} }
@ -271,6 +300,7 @@ static void get_win32_clipboard_bitmap(Image*& image, Palette*& palette)
valid_image = true; valid_image = true;
break; break;
} }
} }
if (!valid_image) { if (!valid_image) {

View File

@ -150,8 +150,7 @@ Layer *NewLayerFromMask(Sprite *src_sprite, Sprite *dst_sprite)
if ((getx >= 0) && (getx < src->w) && if ((getx >= 0) && (getx < src->w) &&
(gety >= 0) && (gety < src->h)) (gety >= 0) && (gety < src->h))
dst->method->putpixel(dst, u, v, dst->putpixel(u, v, src->getpixel(getx, gety));
src->method->getpixel(src, getx, gety));
} }
_image_bitmap_next_bit(d, address); _image_bitmap_next_bit(d, address);
@ -207,8 +206,7 @@ Image* NewImageFromMask(Sprite* src_sprite)
if ((getx >= 0) && (getx < src->w) && if ((getx >= 0) && (getx < src->w) &&
(gety >= 0) && (gety < src->h)) (gety >= 0) && (gety < src->h))
dst->method->putpixel(dst, u, v, dst->putpixel(u, v, src->getpixel(getx, gety));
src->method->getpixel(src, getx, gety));
} }
_image_bitmap_next_bit(d, address); _image_bitmap_next_bit(d, address);

View File

@ -76,7 +76,7 @@ Mask *load_msk_file(const char *filename)
for (i=0; i<8000; i++) { for (i=0; i<8000; i++) {
byte = pack_getc (f); byte = pack_getc (f);
for (c=0; c<8; c++) { for (c=0; c<8; c++) {
mask->bitmap->method->putpixel(mask->bitmap, u, v, byte & (1<<(7-c))); mask->bitmap->putpixel(u, v, byte & (1<<(7-c)));
u++; u++;
if (u == 320) { if (u == 320) {
u = 0; u = 0;

View File

@ -75,11 +75,11 @@ Image *load_pic_file(const char *filename, int *x, int *y, RGB *palette)
} }
/* read image */ /* read image */
image = image_new (IMAGE_INDEXED, w, h); image = image_new(IMAGE_INDEXED, w, h);
for (v=0; v<h; v++) for (v=0; v<h; v++)
for (u=0; u<w; u++) for (u=0; u<w; u++)
image->method->putpixel (image, u, v, pack_getc (f)); image->putpixel(u, v, pack_getc(f));
pack_fclose (f); pack_fclose (f);
return image; return image;
@ -151,7 +151,7 @@ Image *load_pic_file(const char *filename, int *x, int *y, RGB *palette)
case 1: case 1:
for (v=0; v<h; v++) for (v=0; v<h; v++)
for (u=0; u<w; u++) for (u=0; u<w; u++)
image->method->putpixel (image, u, v, pack_getc (f)); image->putpixel(u, v, pack_getc(f));
break; break;
/* bit-per-pixel image data */ /* bit-per-pixel image data */
@ -244,7 +244,7 @@ int save_pic_file(const char *filename, int x, int y, RGB *palette, Image *image
pack_iputw (1, f); /* block type */ pack_iputw (1, f); /* block type */
for (v=0; v<image->h; v++) /* image data */ for (v=0; v<image->h; v++) /* image data */
for (u=0; u<image->w; u++) for (u=0; u<image->w; u++)
pack_putc (image->method->getpixel (image, u, v), f); pack_putc(image->getpixel(u, v), f);
} }
pack_fclose (f); pack_fclose (f);

View File

@ -341,7 +341,7 @@ static int quantize_bitmaps(Image **image, int nimage, RGB *pal, int *bmp_i, int
/* add_progress(image[c_bmp]->h); */ /* add_progress(image[c_bmp]->h); */
for (y=0;y<image[c_bmp]->h;y++) { for (y=0;y<image[c_bmp]->h;y++) {
for (x=0;x<image[c_bmp]->w;x++) { for (x=0;x<image[c_bmp]->w;x++) {
c=image[c_bmp]->method->getpixel(image[c_bmp],x,y); c=image[c_bmp]->getpixel(x,y);
r=_rgba_getr(c)>>2; r=_rgba_getr(c)>>2;
g=_rgba_getg(c)>>2; g=_rgba_getg(c)>>2;
b=_rgba_getb(c)>>2; b=_rgba_getb(c)>>2;

View File

@ -424,9 +424,7 @@ static void merge_zoomed_image16(Image *dst, Image *src,
int sizeof_box, offsetx, offsety; int sizeof_box, offsetx, offsety;
int line_x, line_h, right, bottom; int line_x, line_h, right, bottom;
assert(blend_mode >= 0 && blend_mode < BLEND_MODE_MAX); blender = GrayscaleTraits::get_blender(blend_mode);
blender = _graya_blenders[blend_mode];
box_w = 1<<zoom; box_w = 1<<zoom;
box_h = 1<<zoom; box_h = 1<<zoom;
@ -569,9 +567,7 @@ static void merge_zoomed_image32(Image *dst, Image *src,
int sizeof_box, offsetx, offsety; int sizeof_box, offsetx, offsety;
int line_x, line_h, right, bottom; int line_x, line_h, right, bottom;
assert(blend_mode >= 0 && blend_mode < BLEND_MODE_MAX); blender = RgbTraits::get_blender(blend_mode);
blender = _rgba_blenders[blend_mode];
box_w = 1<<zoom; box_w = 1<<zoom;
box_h = 1<<zoom; box_h = 1<<zoom;