mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-27 06:35:16 +00:00
- 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:
parent
6f9bccd65b
commit
dd003a8f33
15
ChangeLog
15
ChangeLog
@ -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
|
||||
|
8
NEWS.txt
8
NEWS.txt
@ -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
|
||||
|
10
TODO.txt
10
TODO.txt
@ -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;
|
||||
|
2
config.h
2
config.h
@ -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"
|
||||
|
||||
|
@ -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
34
data/jids/canvas.jid
Normal 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
52
data/jids/sprsize.jid
Normal 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>
|
@ -5,7 +5,7 @@
|
||||
\palette ase.pcx
|
||||
\image ase.pcx
|
||||
|
||||
Welcome to ASE 0.6.1
|
||||
Welcome to ASE 0.7
|
||||
|
||||
READ THIS!
|
||||
|
||||
|
@ -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 \
|
||||
|
@ -1,7 +1,7 @@
|
||||
#! /bin/sh
|
||||
|
||||
dir="`pwd`"
|
||||
version=0.6.2
|
||||
version=0.7
|
||||
distdir=ase-$version
|
||||
|
||||
freetype_files="third_party/freetype/ChangeLog \
|
||||
|
97
src/commands/cmd_canvas_size.cpp
Normal file
97
src/commands/cmd_canvas_size.cpp
Normal 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
|
||||
};
|
@ -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;
|
||||
|
||||
|
223
src/commands/cmd_sprite_size.cpp
Normal file
223
src/commands/cmd_sprite_size.cpp
Normal 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
|
||||
};
|
@ -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,
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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[];
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
995
src/raster/image_impl.h
Normal 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
235
src/raster/image_traits.h
Normal 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
|
@ -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,
|
||||
};
|
@ -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,
|
||||
};
|
@ -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,
|
||||
};
|
@ -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,
|
||||
};
|
@ -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,
|
||||
};
|
@ -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)) {
|
||||
|
@ -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);
|
||||
|
@ -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) \
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -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) {
|
||||
|
@ -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) \
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user