- 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>
* src/modules/tools.cpp: Now tiled mode can be specified by X

View File

@ -2,11 +2,13 @@
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).
+ Copy & Paste use Windows clipboard (feature #2577954).
+ Added "Canvas Size" and "Rotate Canvas" commands.
+ Fixed compilation support for gcc 64 bits.
+ Fixed a bug with multiple editors and paste command.
+ 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;
- 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.
- rewritten palette-editor to edit multiple-palettes.
- 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
window is active, the slider of the "Brush Size" must be updated.
- add a consistent error handling.
- drag & drop files in Windows.
- add two DrawClick2:
- DrawClick2FreeHand
- DrawClick2Shape
@ -32,10 +34,6 @@ High priority work
- layer movement between sets in animation-editor;
+ add all the "set" stuff again;
- options to change the curve type (in curedit.c);
- More Commands:
+ resize sprite;
+ rotate sprite (90 CW, CCW, Any Angle);
+ canvas size;
- gaussian blur;
- RGB and HSV effects;
- color-curve stock;

View File

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

View File

@ -81,7 +81,6 @@
<key tool="paint_bucket" shortcut="G" />
<key tool="line" shortcut="L" />
<key tool="curve" shortcut="V" />
<key tool="curve" shortcut="L" />
<key tool="rectangle" shortcut="U" />
<key tool="ellipse" shortcut="O" />
<key tool="ellipse" shortcut="U" />
@ -127,12 +126,23 @@
</menu>
<menu name="&Sprite">
<item command="sprite_properties" name="&Properties..." />
<separator />
<item command="change_image_type" name="&Color Mode..." />
<item command="change_image_type" name="Color &Mode..." />
<separator />
<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="autocrop_sprite" name="&Auto Crop" />
<item command="autocrop_sprite" name="&Trim" />
</menu>
<menu name="&Layer">
<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
\image ase.pcx
Welcome to ASE 0.6.1
Welcome to ASE 0.7
READ THIS!

View File

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

View File

@ -1,7 +1,7 @@
#! /bin/sh
dir="`pwd`"
version=0.6.2
version=0.7
distdir=ase-$version
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) */
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]->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_blur_tool;
extern Command cmd_brush_tool;
extern Command cmd_canvas_size;
extern Command cmd_cel_properties;
extern Command cmd_change_image_type;
extern Command cmd_clear;
@ -114,6 +115,7 @@ extern Command cmd_split_editor_horizontally;
extern Command cmd_split_editor_vertically;
extern Command cmd_spray_tool;
extern Command cmd_sprite_properties;
extern Command cmd_sprite_size;
extern Command cmd_switch_colors;
extern Command cmd_tips;
extern Command cmd_undo;
@ -126,6 +128,7 @@ static Command *commands[] = {
&cmd_background_from_layer,
&cmd_blur_tool,
&cmd_brush_tool,
&cmd_canvas_size,
&cmd_cel_properties,
&cmd_change_image_type,
&cmd_clear,
@ -206,6 +209,7 @@ static Command *commands[] = {
&cmd_split_editor_vertically,
&cmd_spray_tool,
&cmd_sprite_properties,
&cmd_sprite_size,
&cmd_switch_colors,
&cmd_tips,
&cmd_undo,

View File

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

View File

@ -308,12 +308,12 @@ JList get_convmatr_stock()
return data.matrices;
}
#define GET_CONVMATR_DATA(ptr_type, do_job) \
#define GET_CONVMATR_DATA(Traits, do_job) \
div = matrix->div; \
mdata = matrix->data; \
\
GET_MATRIX_DATA \
(ptr_type, \
(Traits::pixel_t, \
src, src_address, \
matrix->w, matrix->h, \
matrix->cx, matrix->cy, \
@ -325,7 +325,7 @@ JList get_convmatr_stock()
mdata++; \
); \
\
color = src->method->getpixel(src, x, y); \
color = image_getpixel_fast<Traits>(src, x, y); \
if (div == 0) { \
*(dst_address++) = color; \
continue; \
@ -364,7 +364,7 @@ void apply_convolution_matrix4(Effect *effect)
r = g = b = a = 0;
GET_CONVMATR_DATA
(ase_uint32,
(RgbTraits,
if (_rgba_geta(color) == 0)
div -= *mdata;
else {
@ -441,7 +441,7 @@ void apply_convolution_matrix2(Effect *effect)
k = a = 0;
GET_CONVMATR_DATA
(ase_uint16,
(GrayscaleTraits,
if (_graya_geta(color) == 0)
div -= *mdata;
else {
@ -503,7 +503,7 @@ void apply_convolution_matrix1(Effect *effect)
r = g = b = index = 0;
GET_CONVMATR_DATA
(ase_uint8,
(IndexedTraits,
r += _rgba_getr(pal->color[color]) * (*mdata);
g += _rgba_getg(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++)
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)
r = data.channel[0][data.ncolors/2];
@ -163,7 +163,7 @@ void apply_median2(Effect *effect)
for (c=0; c<2; c++)
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)
k = data.channel[0][data.ncolors/2];
@ -234,7 +234,7 @@ void apply_median1(Effect *effect)
*(dst_address++) = data.channel[0][data.ncolors/2];
}
else {
color = src->method->getpixel(src, x, y);
color = image_getpixel_fast<IndexedTraits>(src, x, y);
if (effect->target & TARGET_RED_CHANNEL)
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);
b = 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);
}
@ -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++) {
k = 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);
}
@ -798,7 +798,7 @@ static Cel *ase_file_read_cel_chunk(FILE *f, Sprite *sprite, int frame, int imgt
case IMAGE_INDEXED:
for (y=0; y<image->h; y++) {
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);
}
@ -869,7 +869,7 @@ static void ase_file_write_cel_chunk(FILE *f, Cel *cel, Layer *layer, Sprite *sp
case IMAGE_RGB:
for (y=0; y<image->h; y++) {
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_getg(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:
for (y=0; y<image->h; y++) {
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_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:
for (y=0; y<image->h; y++) {
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;
}

View File

@ -555,7 +555,7 @@ static int read_bitfields_image(FILE *f, Image *image, BITMAPINFOHEADER *infohea
g = gscale ? gscale[g]: g;
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;
@ -768,12 +768,12 @@ static bool save_BMP(FileOp *fop)
for (j=0; j<image->w; j++) {
if (bpp == 8) {
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)
fputc(_graya_getv(image->method->getpixel(image, j, i)), f);
fputc(_graya_getv(image_getpixel_fast<GrayscaleTraits>(image, j, i)), f);
}
else {
c = image->method->getpixel(image, j, i);
c = image_getpixel_fast<RgbTraits>(image, j, i);
fputc(_rgba_getb(c), f);
fputc(_rgba_getg(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... */
if (depth == 8) {
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) {
c = image->method->getpixel(image, x, y);
c = image_getpixel_fast<GrayscaleTraits>(image, x, y);
ch = _graya_getv(c);
}
}
else {
if (x < image->w) {
c = image->method->getpixel(image, x, y);
c = image_getpixel_fast<RgbTraits>(image, x, y);
ch = _rgba_getr(c);
}
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);
}
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);
}
}

View File

@ -1682,9 +1682,6 @@ static void line_for_spline(int x1, int y1, int x2, int y2, ToolData *data)
\
/* with mask */ \
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)) \
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) \
x2 = data->mask_x+data->mask->w-1; \
\
if (data->mask->bitmap != NULL) { \
if (Image* bitmap = data->mask->bitmap) { \
addresses_initialize; \
for (x=x1; x<=x2; ++x) { \
if (getpixel(data->mask->bitmap, \
x-data->mask_x, \
y-data->mask_y)) \
if (bitmap->getpixel(x-data->mask_x, y-data->mask_y)) \
processing; \
\
addresses_increment; \
@ -1714,17 +1709,17 @@ static void line_for_spline(int x1, int y1, int x2, int y2, ToolData *data)
addresses_increment; \
}
#define DEFINE_INK_PROCESSING_DST(type, processing) \
DEFINE_INK_PROCESSING(register type *dst_address; , \
dst_address = ((type **)data->dst_image->line)[y]+x1; , \
++dst_address , \
#define DEFINE_INK_PROCESSING_DST(Traits, processing) \
DEFINE_INK_PROCESSING(register Traits::address_t dst_address; , \
dst_address = ((Traits::address_t*)data->dst_image->line)[y]+x1; , \
++dst_address , \
processing)
#define DEFINE_INK_PROCESSING_SRCDST(type, processing) \
DEFINE_INK_PROCESSING(register type *src_address; \
register type *dst_address; , \
src_address = ((type **)data->src_image->line)[y]+x1; \
dst_address = ((type **)data->dst_image->line)[y]+x1; , \
#define DEFINE_INK_PROCESSING_SRCDST(Traits, processing) \
DEFINE_INK_PROCESSING(register Traits::address_t src_address; \
register Traits::address_t dst_address; , \
src_address = ((Traits::address_t*)data->src_image->line)[y]+x1; \
dst_address = ((Traits::address_t*)data->dst_image->line)[y]+x1; , \
++src_address; \
++dst_address; , \
processing)
@ -1738,7 +1733,7 @@ static void ink_hline32_opaque(int x1, int y, int x2, ToolData *data)
int c = data->color;
DEFINE_INK_PROCESSING_DST
(ase_uint32,
(RgbTraits,
*dst_address = c );
}
@ -1747,7 +1742,7 @@ static void ink_hline16_opaque(int x1, int y, int x2, ToolData *data)
int c = data->color;
DEFINE_INK_PROCESSING_DST
(ase_uint16,
(GrayscaleTraits,
*dst_address = c );
}
@ -1756,7 +1751,7 @@ static void ink_hline8_opaque(int x1, int y, int x2, ToolData *data)
int c = data->color;
DEFINE_INK_PROCESSING_DST
(ase_uint8,
(IndexedTraits,
*dst_address = c );
/* 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;
DEFINE_INK_PROCESSING_SRCDST
(ase_uint32,
(RgbTraits,
*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;
DEFINE_INK_PROCESSING_SRCDST
(ase_uint16,
(GrayscaleTraits,
*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;
DEFINE_INK_PROCESSING_SRCDST
(ase_uint8,
(IndexedTraits,
{
c = _rgba_blend_normal(pal->color[*src_address], tc, opacity);
*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;
DEFINE_INK_PROCESSING_SRCDST
(ase_uint32,
(RgbTraits,
{
c = 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;
DEFINE_INK_PROCESSING_SRCDST
(ase_uint16,
(GrayscaleTraits,
{
c = 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;
DEFINE_INK_PROCESSING_SRCDST
(ase_uint8,
(IndexedTraits,
{
c = 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;
DEFINE_INK_PROCESSING_SRCDST
(ase_uint32,
(RgbTraits,
if (*src_address == other_color) {
*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;
DEFINE_INK_PROCESSING_SRCDST
(ase_uint16,
(GrayscaleTraits,
if (*src_address == other_color) {
*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;
DEFINE_INK_PROCESSING_SRCDST
(ase_uint8,
(IndexedTraits,
if (*src_address == other_color) {
c = _rgba_blend_normal(pal->color[*src_address], tc, opacity);
*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;
DEFINE_INK_PROCESSING_SRCDST
(ase_uint32,
(RgbTraits,
{
JUMBLE_XY_IN_UV();
*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;
DEFINE_INK_PROCESSING_SRCDST
(ase_uint16,
(GrayscaleTraits,
{
JUMBLE_XY_IN_UV();
*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;
DEFINE_INK_PROCESSING_SRCDST
(ase_uint8,
(IndexedTraits,
{
JUMBLE_XY_IN_UV();

View File

@ -53,7 +53,7 @@ enum {
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 _graya_blenders[];

View File

@ -52,7 +52,7 @@
\
memcpy((col)->ptr, \
(col)->data, \
DIRTY_LINE_SIZE((col)->w)); \
dirty_line_size(dirty, (col)->w)); \
}
#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].data = jrealloc(row->col[u].data, \
DIRTY_LINE_SIZE(row->col[u].w));
dirty_line_size(dirty, row->col[u].w));
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].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);
@ -268,9 +268,8 @@ void dirty_putpixel(Dirty* dirty, int x, int y)
return;
if ((dirty->mask->bitmap) &&
!(dirty->mask->bitmap->method->getpixel(dirty->mask->bitmap,
x-dirty->mask->x,
y-dirty->mask->y)))
!(dirty->mask->bitmap->getpixel(x-dirty->mask->x,
y-dirty->mask->y)))
return;
}
@ -310,7 +309,7 @@ void dirty_putpixel(Dirty* dirty, int x, int y)
if (u < row->cols-1 && x+1 == (col+1)->x)
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;
}
/* the pixel is to left of the column */
@ -319,9 +318,9 @@ void dirty_putpixel(Dirty* dirty, int x, int y)
--col->x;
++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;
}
/* the next column is more too far */
@ -335,8 +334,8 @@ void dirty_putpixel(Dirty* dirty, int x, int y)
col->x = x;
col->w = 1;
col->flags = 0;
col->data = jmalloc(DIRTY_LINE_SIZE(1));
col->ptr = IMAGE_ADDRESS(dirty->image, x, y);
col->data = jmalloc(dirty_line_size(dirty, 1));
col->ptr = image_address(dirty->image, x, y);
}
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) {
for (; x1<=x2; ++x1)
if (dirty->mask->bitmap->method->getpixel(dirty->mask->bitmap,
x1-dirty->mask->x,
y-dirty->mask->y))
if (dirty->mask->bitmap->getpixel(x1-dirty->mask->x,
y-dirty->mask->y))
break;
for (; x2>=x1; x2--)
if (dirty->mask->bitmap->method->getpixel(dirty->mask->bitmap,
x2-dirty->mask->x,
y-dirty->mask->y))
if (dirty->mask->bitmap->getpixel(x2-dirty->mask->x,
y-dirty->mask->y))
break;
}
@ -446,9 +443,8 @@ void dirty_hline(Dirty* dirty, int x1, int y, int x2)
if (dirty->mask && dirty->mask->bitmap) {
for (x=x1; x<=x2; ++x) {
if (!dirty->mask->bitmap->method->getpixel(dirty->mask->bitmap,
x-dirty->mask->x,
y-dirty->mask->y)) {
if (!dirty->mask->bitmap->getpixel(x-dirty->mask->x,
y-dirty->mask->y)) {
continue;
}
@ -471,7 +467,7 @@ void dirty_hline(Dirty* dirty, int x1, int y, int x2)
memcpy((col+1)->ptr,
(col+1)->data,
DIRTY_LINE_SIZE((col+1)->w));
dirty_line_size(dirty, (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->data = jrealloc(col->data, DIRTY_LINE_SIZE(col->w));
col->data = jrealloc(col->data, dirty_line_size(dirty, col->w));
goto done;
}
/* 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,
col->data,
DIRTY_LINE_SIZE(col->w));
dirty_line_size(dirty, col->w));
}
--col->x;
++col->w;
col->data = jrealloc(col->data, DIRTY_LINE_SIZE(col->w));
col->ptr = IMAGE_ADDRESS(dirty->image, x, y);
col->data = jrealloc(col->data, dirty_line_size(dirty, col->w));
col->ptr = image_address(dirty->image, x, y);
goto done;
}
else if (x < col->x)
@ -523,8 +519,8 @@ void dirty_hline(Dirty* dirty, int x1, int y, int x2)
col->x = x;
col->w = 1;
col->flags = 0;
col->data = jmalloc(DIRTY_LINE_SIZE(1));
col->ptr = IMAGE_ADDRESS(dirty->image, x, y);
col->data = jmalloc(dirty_line_size(dirty, 1));
col->ptr = image_address(dirty->image, x, y);
done:;
}
@ -556,11 +552,11 @@ void dirty_hline(Dirty* dirty, int x1, int y, int x2)
/* extend to left */
col->w += 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 */
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;
}
/* extend this column to "x2" */
@ -580,8 +576,8 @@ void dirty_hline(Dirty* dirty, int x1, int y, int x2)
col->x = x1;
col->w = x2-x1+1;
col->flags = 0;
col->data = jmalloc(DIRTY_LINE_SIZE(col->w));
col->ptr = IMAGE_ADDRESS(dirty->image, x1, y);
col->data = jmalloc(dirty_line_size(dirty, col->w));
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)
{
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 (u=0; u<dirty->row[v].cols; ++u) {
@ -666,7 +662,7 @@ void dirty_restore_image_data(Dirty* dirty)
register DirtyCol* col;
DirtyRow* rowend;
DirtyCol* colend;
int shift = IMAGE_SHIFT(dirty->image);
int shift = image_shift(dirty->image);
row = dirty->row;
rowend = row+dirty->rows;

View File

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

View File

@ -20,8 +20,6 @@
#include <assert.h>
#include <allegro.h>
/* #include <allegro/color.h> */
/* #include <allegro/gfx.h> */
#include <string.h>
#include <stdexcept>
@ -29,26 +27,10 @@
#include "raster/blend.h"
#include "raster/brush.h"
#include "raster/image.h"
#ifndef USE_ALLEGRO_IMAGE
#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
#include "raster/image_impl.h"
#include "raster/palette.h"
//////////////////////////////////////////////////////////////////////
Image::Image(int imgtype, int w, int h)
: GfxObj(GFXOBJ_IMAGE)
@ -56,36 +38,27 @@ Image::Image(int imgtype, int w, int h)
this->imgtype = imgtype;
this->w = w;
this->h = h;
#ifndef USE_ALLEGRO_IMAGE
this->method = image_methods[imgtype];
#else
this->method = &alleg_methods;
#endif
this->dat = NULL;
this->line = NULL;
#ifdef USE_ALLEGRO_IMAGE
this->bmp = NULL;
#endif
assert(this->method);
this->method->init(this);
}
Image::~Image()
{
#ifndef USE_ALLEGRO_IMAGE
if (this->dat) delete[] this->dat;
if (this->line) delete[] this->line;
#else
destroy_bitmap(this->bmp);
#endif
}
//////////////////////////////////////////////////////////////////////
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)
@ -114,7 +87,7 @@ int image_depth(Image* image)
int image_getpixel(const Image* image, int x, int y)
{
if ((x >= 0) && (y >= 0) && (x < image->w) && (y < image->h))
return image->method->getpixel(image, x, y);
return image->getpixel(x, y);
else
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)
{
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)
{
image->method->clear (image, color);
image->clear(color);
}
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)
{
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)
@ -169,7 +142,7 @@ void image_hline(Image* image, int x1, int y, int x2, int color)
if (x1 < 0) x1 = 0;
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)
@ -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;
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)
@ -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 (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
@ -349,12 +322,12 @@ void image_ellipsefill(Image* image, int x1, int y1, int x2, int y2, int color)
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;
float hue, s, v;
@ -378,14 +351,14 @@ void image_convert(Image* dst, const Image* src)
case IMAGE_GRAYSCALE:
for (y=0; y<h; y++) {
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),
_rgba_getg(c),
_rgba_getb(c), &hue, &s, &v);
v = v * 255.0f;
dst->method->putpixel(dst, x, y,
_graya((int)MID(0, v, 255),
_rgba_geta(c)));
image_putpixel_fast<GrayscaleTraits>(dst, x, y,
_graya((int)MID(0, v, 255),
_rgba_geta(c)));
}
}
break;
@ -394,14 +367,14 @@ void image_convert(Image* dst, const Image* src)
case IMAGE_INDEXED:
for (y=0; y<h; y++) {
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))
dst->method->putpixel(dst, x, y, 0);
image_putpixel_fast<IndexedTraits>(dst, x, y, 0);
else
dst->method->putpixel(dst, x, y,
makecol8(_rgba_getr(c),
_rgba_getg(c),
_rgba_getb(c)));
image_putpixel_fast<IndexedTraits>(dst, x, y,
makecol8(_rgba_getr(c),
_rgba_getg(c),
_rgba_getb(c)));
}
}
break;
@ -415,12 +388,12 @@ void image_convert(Image* dst, const Image* src)
case IMAGE_RGB:
for (y=0; y<h; y++) {
for (x=0; x<w; x++) {
c = src->method->getpixel(src, x, y);
dst->method->putpixel(dst, x, y,
_rgba(_graya_getv(c),
_graya_getv(c),
_graya_getv(c),
_graya_geta(c)));
c = image_getpixel_fast<GrayscaleTraits>(src, x, y);
image_putpixel_fast<RgbTraits>(dst, x, y,
_rgba(_graya_getv(c),
_graya_getv(c),
_graya_getv(c),
_graya_geta(c)));
}
}
break;
@ -429,14 +402,14 @@ void image_convert(Image* dst, const Image* src)
case IMAGE_INDEXED:
for (y=0; y<h; y++) {
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))
dst->method->putpixel(dst, x, y, 0);
image_putpixel_fast<IndexedTraits>(dst, x, y, 0);
else
dst->method->putpixel(dst, x, y,
makecol8(_graya_getv(c),
_graya_getv(c),
_graya_getv(c)));
image_putpixel_fast<IndexedTraits>(dst, x, y,
makecol8(_graya_getv(c),
_graya_getv(c),
_graya_getv(c)));
}
}
break;
@ -450,14 +423,14 @@ void image_convert(Image* dst, const Image* src)
case IMAGE_RGB:
for (y=0; y<h; y++) {
for (x=0; x<w; x++) {
c = src->method->getpixel(src, x, y);
c = image_getpixel_fast<IndexedTraits>(src, x, y);
if (!c)
dst->method->putpixel(dst, x, y, 0);
image_putpixel_fast<RgbTraits>(dst, x, y, 0);
else
dst->method->putpixel(dst, x, y,
_rgba(getr8(c),
getg8(c),
getb8(c), 255));
image_putpixel_fast<RgbTraits>(dst, x, y,
_rgba(getr8(c),
getg8(c),
getb8(c), 255));
}
}
break;
@ -466,14 +439,14 @@ void image_convert(Image* dst, const Image* src)
case IMAGE_GRAYSCALE:
for (y=0; y<h; y++) {
for (x=0; x<w; x++) {
c = src->method->getpixel(src, x, y);
c = image_getpixel_fast<GrayscaleTraits>(src, x, y);
if (!c)
dst->method->putpixel(dst, x, y, 0);
image_putpixel_fast<GrayscaleTraits>(dst, x, y, 0);
else {
rgb_to_hsv(getr8(c), getg8(c), getb8(c), &hue, &s, &v);
v = v * 255.0f;
dst->method->putpixel(dst, x, y,
_graya((int)MID(0, v, 255), 255));
image_putpixel_fast<GrayscaleTraits>(dst, x, y,
_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 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 { \
for (u = u_begin; u u_op u_final; u u_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; \
} \
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
}

View File

@ -19,51 +19,13 @@
#ifndef RASTER_IMAGE_H
#define RASTER_IMAGE_H
/* #define USE_ALLEGRO_IMAGE */
#include <allegro/color.h>
#include "raster/gfxobj.h"
#include "raster/blend.h"
#define _rgba_r_shift 0
#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)))
class Palette;
#define _graya_v_shift 0
#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 */
// Image Types
enum {
IMAGE_RGB,
IMAGE_GRAYSCALE,
@ -71,9 +33,12 @@ enum {
IMAGE_BITMAP
};
enum ResizeMethod {
RESIZE_METHOD_NEAREST_NEIGHBOR,
RESIZE_METHOD_BILINEAR,
};
struct BITMAP;
/* struct Brush; */
struct ImageMethods;
class Image : public GfxObj
{
@ -82,27 +47,18 @@ public:
int w, h;
ase_uint8* dat; /* pixmap data */
ase_uint8** line; /* start of each scanline */
ImageMethods* method;
#ifdef USE_ALLEGRO_IMAGE
BITMAP* bmp;
#endif
Image(int imgtype, int w, int h);
virtual ~Image();
};
struct ImageMethods
{
void (*init)(Image* image);
int (*getpixel)(const Image* image, int x, int y);
void (*putpixel)(Image* image, int x, int y, int color);
void (*clear)(Image* image, int color);
void (*copy)(Image* dst, const Image* src, int x, int y);
void (*merge)(Image* dst, const Image* src, int x, int y, int opacity,
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);
virtual int getpixel(int x, int y) const = 0;
virtual void putpixel(int x, int y, int color) = 0;
virtual void clear(int color) = 0;
virtual void copy(const Image* src, int x, int y) = 0;
virtual void merge(const Image* src, int x, int y, int opacity, int blend_mode) = 0;
virtual void hline(int x1, int y, int x2, int color) = 0;
virtual void rectfill(int x1, int y1, int x2, int y2, int color) = 0;
virtual void to_allegro(BITMAP* bmp, int x, int y) const = 0;
};
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_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_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(const Image* image, BITMAP* bmp, int x, int y);
void image_to_allegro(Image* image, BITMAP* bmp, int x, int y);
void image_convert(Image* dst, const Image* src);
void image_convert(const Image* src, Image* dst);
void image_resize(const Image* src, Image* dst, ResizeMethod method, Palette* palette, RGB_MAP* rgb_map);
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);
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 */

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;
}
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)
{
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_blend_mode(Layer* layer, int blend_mode);
void layer_get_cels(const Layer* layer, JList cels);
/* for LAYER_IMAGE */
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 (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; \
} \
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 (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);
g = _rgba_getg(c);
@ -258,7 +258,7 @@ Image *image_rgb_to_indexed(Image *src_image,
else
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;
}
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
* specified coordinates there're background this routine will return
@ -754,7 +759,7 @@ int sprite_get_memsize(Sprite* sprite)
image = sprite->stock->image[i];
if (image != NULL)
size += IMAGE_LINE_SIZE(image, image->w) * image->h;
size += image_line_size(image, image->w) * image->h;
}
return size;

View File

@ -137,6 +137,7 @@ void sprite_generate_mask_boundaries(Sprite* sprite);
Layer* sprite_index2layer(Sprite* sprite, int index);
int sprite_layer2index(const Sprite* sprite, const Layer* layer);
int sprite_count_layers(const Sprite* sprite);
void sprite_get_cels(Sprite* sprite, JList cels);
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
* new "image"; you must free the old image before, e.g:
* @code
* Image* old_image = stock_get_image (stock, index);
* if (old_image) image_free (old_image);
* stock_replace_image (stock, index, new_image);
* Image* old_image = stock_get_image(stock, index);
* if (old_image)
* image_free(old_image);
* stock_replace_image(stock, index, new_image);
* @endcode
*/
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(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* )
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;
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;
}
}
@ -656,11 +656,11 @@ static void chunk_image_invert(UndoStream* stream, UndoChunkImage* chunk, int st
chunk_image_new(stream, image, x, y, w, h);
/* restore the old image portion */
size = IMAGE_LINE_SIZE(image, chunk->w);
size = image_line_size(image, chunk->w);
ptr = chunk->data;
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;
}
}
@ -1537,11 +1537,11 @@ static Dirty *read_raw_dirty(ase_uint8* raw_data)
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].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);
}
@ -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].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);
}
}
@ -1590,7 +1590,7 @@ static int get_raw_dirty_size(Dirty *dirty)
size += 4; /* y, cols (WORD[2]) */
for (u=0; u<dirty->row[v].cols; u++) {
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 */
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++)
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->h); /* height */
size = IMAGE_LINE_SIZE(image, image->w);
size = image_line_size(image, image->w);
for (c=0; c<image->h; c++)
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)
{
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
// `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;
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 { \
for (u = u_begin; u u_op u_final; u u_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; \
} \
if (v == v_final) \
@ -77,8 +77,7 @@ bool get_shrink_rect2(int *x1, int *y1, int *x2, int *y2,
do { \
for (u = u_begin; u u_op u_final; u u_add) { \
for (v = v_begin; v v_op v_final; v v_add) { \
if (image->method->getpixel (image, U, V) != \
refimage->method->getpixel (refimage, U, V)) \
if (image->getpixel(U, V) != refimage->getpixel(U, V)) \
break; \
} \
if (v == v_final) \

View File

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

View File

@ -104,7 +104,7 @@ static void set_win32_clipboard_bitmap(Image* image, Palette* palette)
ase_uint32 c;
for (int y=image->h-1; y>=0; --y)
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) |
(_rgba_getg(c) << 8) |
(_rgba_getr(c) << 16) |
@ -117,7 +117,7 @@ static void set_win32_clipboard_bitmap(Image* image, Palette* palette)
ase_uint16 c;
for (int y=image->h-1; y>=0; --y)
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) |
(_graya_getv(c) << 8) |
(_graya_getv(c) << 16) |
@ -139,7 +139,7 @@ static void set_win32_clipboard_bitmap(Image* image, Palette* palette)
+ palette_entries*sizeof(RGBQUAD));
for (int y=image->h-1; y>=0; --y) {
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;
}
@ -169,7 +169,13 @@ static void get_win32_clipboard_bitmap(Image*& image, Palette*& palette)
return;
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 {
image = image_new(bi->bmiHeader.biBitCount == 8 ? IMAGE_INDEXED:
IMAGE_RGB,
@ -178,51 +184,72 @@ static void get_win32_clipboard_bitmap(Image*& image, Palette*& palette)
bool valid_image = false;
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) {
for (int x=0; x<image->w; ++x) {
c = *(src++);
// image->method->putpixel(image, x, y,
// _rgba((c & bv5->bV5RedMask) >> r_shift,
// (c & bv5->bV5GreenMask) >> g_shift,
// (c & bv5->bV5BlueMask) >> b_shift,
// (c & bv5->bV5AlphaMask) >> a_shift));
image->method->putpixel(image, x, y,
_rgba((c & 0x00ff0000) >> 16,
(c & 0x0000ff00) >> 8,
(c & 0x000000ff) >> 0,
(c & 0xff000000) >> 24));
// 32 BPP
case 32:
if (bi->bmiHeader.biCompression == BI_BITFIELDS) {
ase_uint32* src = (ase_uint32*)(((ase_uint8*)bi)+bi->bmiHeader.biSize+sizeof(RGBQUAD)*3);
ase_uint32 c;
ase_uint32 r_mask = (ase_uint32)*((ase_uint32*)&bi->bmiColors[0]);
ase_uint32 g_mask = (ase_uint32)*((ase_uint32*)&bi->bmiColors[1]);
ase_uint32 b_mask = (ase_uint32)*((ase_uint32*)&bi->bmiColors[2]);
ase_uint32 r_shift = get_shift_from_mask(r_mask);
ase_uint32 g_shift = get_shift_from_mask(g_mask);
ase_uint32 b_shift = get_shift_from_mask(b_mask);
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;
break;
}
// 24 BPP
case 24: {
ase_uint8* src = (((ase_uint8*)bi)+bi->bmiHeader.biSize);
ase_uint8 r, g, b;
int padding = (4-(image->w*3)&3)&3;
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) {
b = *(src++);
g = *(src++);
r = *(src++);
image->method->putpixel(image, x, y, _rgba(r, g, b, 255));
*(dst++) = _rgba(r, g, b, 255);
}
src += padding;
}
valid_image = true;
break;
}
// 16 BPP
case 16: {
// TODO I am not sure if this really works
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)];
g = _rgb_scale_6[((b2 & 0x07e0) >> 5)];
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;
}
valid_image = true;
break;
}
// 8 BPP
case 8: {
int colors = bi->bmiHeader.biClrUsed > 0 ? bi->bmiHeader.biClrUsed: 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 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;
}
@ -271,6 +300,7 @@ static void get_win32_clipboard_bitmap(Image*& image, Palette*& palette)
valid_image = true;
break;
}
}
if (!valid_image) {

View File

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

View File

@ -75,11 +75,11 @@ Image *load_pic_file(const char *filename, int *x, int *y, RGB *palette)
}
/* read image */
image = image_new (IMAGE_INDEXED, w, h);
image = image_new(IMAGE_INDEXED, w, h);
for (v=0; v<h; v++)
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);
return image;
@ -151,7 +151,7 @@ Image *load_pic_file(const char *filename, int *x, int *y, RGB *palette)
case 1:
for (v=0; v<h; v++)
for (u=0; u<w; u++)
image->method->putpixel (image, u, v, pack_getc (f));
image->putpixel(u, v, pack_getc(f));
break;
/* 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 */
for (v=0; v<image->h; v++) /* image data */
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);

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); */
for (y=0;y<image[c_bmp]->h;y++) {
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;
g=_rgba_getg(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 line_x, line_h, right, bottom;
assert(blend_mode >= 0 && blend_mode < BLEND_MODE_MAX);
blender = _graya_blenders[blend_mode];
blender = GrayscaleTraits::get_blender(blend_mode);
box_w = 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 line_x, line_h, right, bottom;
assert(blend_mode >= 0 && blend_mode < BLEND_MODE_MAX);
blender = _rgba_blenders[blend_mode];
blender = RgbTraits::get_blender(blend_mode);
box_w = 1<<zoom;
box_h = 1<<zoom;