mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-18 16:21:07 +00:00
Added thumbnails, tooltips, and now the file routines don't use PACKFILE (just FILE from stdio).
This commit is contained in:
parent
112bde13c8
commit
3290dfb7d5
42
ChangeLog
42
ChangeLog
@ -1,3 +1,45 @@
|
||||
2008-02-10 David A. Capello <dacap@users.sourceforge.net>
|
||||
|
||||
* src/widgets/fileview.c: Finished with thumbnails generation.
|
||||
|
||||
* src/commands/cmd_open_file.c (monitor_free): Added to join the
|
||||
thread. This fix bugs when you close the program and there're
|
||||
files loading: all threads are joined.
|
||||
|
||||
* src/modules/gui.c (remove_gui_monitor): Added.
|
||||
(add_gui_monitor): Now it receives a 'free' routine too (to
|
||||
destroy the 'data' of the monitor).
|
||||
|
||||
* src/test/test_errno.c: Added a test to check errno
|
||||
thread-safety.
|
||||
|
||||
2008-02-09 David A. Capello <dacap@users.sourceforge.net>
|
||||
|
||||
* src/jinete/jmanager.c (jmanager_remove_msg_filter):
|
||||
* src/raster/undo.c (chunk_set_mask_invert): Fixed more memory leaks.
|
||||
|
||||
2008-02-08 David A. Capello <dacap@users.sourceforge.net>
|
||||
|
||||
* src/modules/sprites.c (exit_module_sprites):
|
||||
* src/core/core.c (core_exit):
|
||||
* src/widgets/colbar.c (color_bar_msg_proc):
|
||||
* src/raster/layer.c (layer_free):
|
||||
* src/jinete/jaccel.c (jaccel_free):
|
||||
* src/widgets/tabs.c (calculate_hot):
|
||||
* src/core/dirs.c (dirs_cat_dirs): Fixed more memory leaks
|
||||
(the leaks in exit routines aren't too critical, but the
|
||||
other yes).
|
||||
|
||||
* src/jinete/jmanager.c (jmanager_generate_messages): Fixed a
|
||||
memory leak when replacing the value of 'widgets' field of a
|
||||
JMessage.
|
||||
|
||||
* src/jinete/jlist.c (jlist_free): Fixed a big memory leak (for
|
||||
every linked list JList in the program, the 'list->end' field was
|
||||
never freed).
|
||||
|
||||
* src/core/file_system.c (struct FileItem): Added thumbnail field.
|
||||
|
||||
2008-02-04 David A. Capello <dacap@users.sourceforge.net>
|
||||
|
||||
* src/dialogs/filesel.c: Done (navigation history added, and
|
||||
|
17
INSTALL.txt
17
INSTALL.txt
@ -35,3 +35,20 @@ UNINSTALLATION
|
||||
===================================
|
||||
|
||||
Run "make uninstall".
|
||||
|
||||
|
||||
===================================
|
||||
SUBVERSION
|
||||
===================================
|
||||
|
||||
If you're download ASE from the Subversion repository, after
|
||||
updating I recommend you to do:
|
||||
|
||||
~/ase-trunk/$ make clean
|
||||
~/ase-trunk/$ ./fix.sh
|
||||
~/ase-trunk/$ make
|
||||
|
||||
Also, you can make dependencies of the files (if you are trying to
|
||||
hack the ASE source code):
|
||||
|
||||
~/ase-trunk/$ sh misc/deps.sh
|
||||
|
7
NEWS.txt
7
NEWS.txt
@ -7,9 +7,12 @@ NEWS
|
||||
|
||||
+ Added support to load and save PNG files (through 'libpng').
|
||||
+ Replaced the "List" menu with the tabs selector.
|
||||
+ Better file selector.
|
||||
+ Better file selector with thumbnails.
|
||||
+ In Windows: now you can navigate through Desktop, My Documents,
|
||||
My Computer, etc.
|
||||
+ Optimized the loading/saving operations (using threads).
|
||||
+ Restructured all the menus (more user friendly options).
|
||||
- Temporaly removed a lot of complex functionality:
|
||||
- Temporaly removed a lot of complex functionality:
|
||||
Mask-Repository (but you can use .msk files yet), Draw-Text,
|
||||
Layer-Sets and Linked-Cels.
|
||||
+ New XML format for the menus.
|
||||
|
10
TODO.txt
10
TODO.txt
@ -3,8 +3,13 @@ High priority work
|
||||
|
||||
- search for TODO;
|
||||
- rename jcombox.c to jcombobox.c
|
||||
- remove the jfilesel.c
|
||||
- remove USE_PRECOMPILED_HEADER
|
||||
- fix copyright years (2001-2008)
|
||||
- fix a bug in the film editor when move the separator (panel) outside
|
||||
the screen (to left or right)
|
||||
- 'jfile.c' should use 'jxml.c', because there are duplicate code:
|
||||
two (precarious) XML parsers.
|
||||
- the user_data of hook_signal should be void*.
|
||||
- ver por el nuevo load_font de Allegro.
|
||||
- complete palette operations, and palette editor (it needs a slider
|
||||
@ -60,14 +65,11 @@ Wish-list
|
||||
position from the starting point of movement;
|
||||
+ make drawing the 'marching-ants-rectangle' a prioritaire thing to
|
||||
draw (when move it).
|
||||
- for Jinete:
|
||||
+ add columns handle to list-boxes;
|
||||
+ add icons handle to all widgets (mainly button, list-items, and labels);
|
||||
+ add tree widget;
|
||||
|
||||
Low priority stuff
|
||||
------------------
|
||||
|
||||
- add more unit-tests.
|
||||
- test routines: load/save_pic_file, load/save_msk_file,
|
||||
load/save_col_file.
|
||||
- fix the fli reader (both Allegro and Gfli): when a frame hasn't
|
||||
|
2
config.h
2
config.h
@ -27,7 +27,7 @@
|
||||
#define PACKAGE "ase"
|
||||
#define VERSION "0.6"
|
||||
#define WEBSITE "http://www.aseprite.org/"
|
||||
#define BUGREPORT "ase-help@lists.sourceforge.net"
|
||||
#define BUGREPORT "aseprite@googlegroups.com"
|
||||
#define COPYRIGHT "Copyright (C) 2001-2008 David A. Capello"
|
||||
|
||||
#define PRINTF verbose_printf
|
||||
|
@ -7,10 +7,10 @@
|
||||
<box vertical>
|
||||
<box horizontal>
|
||||
<box horizontal noborders>
|
||||
<button text="" name="goback" bevel="2 0 2 0" />
|
||||
<button text="" name="goforward" bevel="0 2 0 2" />
|
||||
<button text="" name="goback" bevel="2 0 2 0" tooltip="Go back one folder" />
|
||||
<button text="" name="goforward" bevel="0 2 0 2" tooltip="Go forward one folder" />
|
||||
</box>
|
||||
<button text="" name="goup" />
|
||||
<button text="" name="goup" tooltip="Up to parent folder\n(Backspace)" />
|
||||
<combobox name="location" expansive />
|
||||
</box>
|
||||
<box vertical expansive name="box" />
|
||||
@ -23,7 +23,7 @@
|
||||
<box horizontal expansive />
|
||||
<box horizontal homogeneous>
|
||||
<button text="&OK" name="ok" magnetic width="60" />
|
||||
<button text="&Cancel" />
|
||||
<button text="&Cancel" name="cancel" />
|
||||
</box>
|
||||
</box>
|
||||
</box>
|
||||
|
@ -15,8 +15,8 @@
|
||||
<label text="Height:" />
|
||||
</box>
|
||||
<box vertical homogeneous expansive>
|
||||
<entry expansive name="width" maxsize=8 magnetic />
|
||||
<entry expansive name="height" maxsize=8 />
|
||||
<entry expansive name="width" maxsize=8 magnetic tooltip="Width of the new sprite (in pixels)" />
|
||||
<entry expansive name="height" maxsize=8 tooltip="Height of the new sprite (in pixels)" />
|
||||
</box>
|
||||
</box>
|
||||
</box>
|
||||
@ -24,9 +24,9 @@
|
||||
<box vertical>
|
||||
<separator text="Color Mode:" left horizontal />
|
||||
<box vertical homogeneous>
|
||||
<radio name="radio1" text="&RGB Color" group=1 />
|
||||
<radio name="radio2" text="&Grayscale" group=1 />
|
||||
<radio name="radio3" text="&Indexed" group=1 />
|
||||
<radio name="radio1" text="&RGB Color" group=1 tooltip="RGBA color mode\n(32 bits per pixel)" />
|
||||
<radio name="radio2" text="&Grayscale" group=1 tooltip="Value and Alpha\n(16 bits per pixel)" />
|
||||
<radio name="radio3" text="&Indexed" group=1 tooltip="Using a palette of 256 colors\n(8 bits per pixel)" />
|
||||
</box>
|
||||
</box>
|
||||
</box>
|
||||
|
@ -7,21 +7,16 @@
|
||||
|
||||
Welcome to ASE 0.6
|
||||
|
||||
You can find help in ASE Wiki:
|
||||
http://www.aseprite.org/wiki/
|
||||
READ THIS!
|
||||
|
||||
Report bugs to:
|
||||
ase-help@lists.sourceforge.net
|
||||
**********************************************************************
|
||||
\split
|
||||
\image nodither.pcx
|
||||
This is the old drawing method for RGB images. Without dithering.
|
||||
\next
|
||||
\image dither.pcx
|
||||
Now, you can configure to use this new ordered dithering method.
|
||||
\done
|
||||
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.
|
||||
|
||||
See "Tool/Options" menu or press <Ctrl+Shift+O>.
|
||||
Website: http://www.aseprite.org/
|
||||
|
||||
Report bugs to: aseprite@googlegroups.com
|
||||
**********************************************************************
|
||||
Use the <1>, <2>, <3>, <4>, <5> and <6> keys to set the zoom in the
|
||||
current editor's viewport.
|
||||
@ -116,6 +111,16 @@ change the coordinates manually) will be appears.
|
||||
Select a color in the color-bar using the <Ctrl> key will show you
|
||||
this mini-palette.
|
||||
**********************************************************************
|
||||
\split
|
||||
\image nodither.pcx
|
||||
A RGB image without dithering.
|
||||
\next
|
||||
\image dither.pcx
|
||||
Ordered dithering method.
|
||||
\done
|
||||
|
||||
See "Tool/Options" menu or press <Ctrl+Shift+O>.
|
||||
**********************************************************************
|
||||
\image lua.pcx
|
||||
|
||||
Do you want to write Lua scripts to generate images or create
|
||||
@ -129,4 +134,4 @@ And remember look for updates in:
|
||||
|
||||
http://www.aseprite.org/
|
||||
|
||||
Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007 by David A. Capello
|
||||
Copyright (C) 2001-2008 by David A. Capello
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright (C) 2001-2005, 2007 by David A. Capello -*-Makefile-*-
|
||||
# Copyright (C) 2001-2008 by David A. Capello -*-Makefile-*-
|
||||
# Manual configuration
|
||||
# (in Unix like systems you can use ./fix.sh script)
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
|
||||
#DEBUGMODE = 1
|
||||
#PROFILE = 1
|
||||
#MEMLEAK = 1
|
||||
|
||||
######################################################################
|
||||
# Default Unix directory to look for ASE data (to this path will be
|
||||
|
@ -25,7 +25,7 @@ ifdef PROFILE
|
||||
LFLAGS += -pg
|
||||
else
|
||||
ifdef DEBUGMODE
|
||||
CFLAGS += -g3
|
||||
CFLAGS += -g3 -DDEBUGMODE
|
||||
LFLAGS += -g3
|
||||
else
|
||||
CFLAGS += -s -O3 -DNDEBUG
|
||||
@ -33,6 +33,10 @@ else
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef MEMLEAK
|
||||
CFLAGS += -DMEMLEAK
|
||||
endif
|
||||
|
||||
ifdef DEFAULT_PREFIX
|
||||
CFLAGS += -DDEFAULT_PREFIX="\"$(DEFAULT_PREFIX)\""
|
||||
endif
|
||||
|
@ -150,6 +150,7 @@ COMMON_SOURCES = \
|
||||
src/jinete/jtextbox.c \
|
||||
src/jinete/jtheme.c \
|
||||
src/jinete/jthread.c \
|
||||
src/jinete/jtooltips.c \
|
||||
src/jinete/jview.c \
|
||||
src/jinete/jwidget.c \
|
||||
src/jinete/jwindow.c \
|
||||
@ -218,11 +219,6 @@ COMMON_SOURCES = \
|
||||
src/widgets/target.c \
|
||||
src/widgets/toolbar.c
|
||||
|
||||
ifdef WIN32
|
||||
COMMON_SOURCES += src/core/file_system_win32.c
|
||||
else
|
||||
endif
|
||||
|
||||
ifdef USE_X86_INT_MULT
|
||||
COMMON_SOURCES += src/raster/x86/int_mult.s
|
||||
endif
|
||||
|
@ -22,6 +22,11 @@ ifdef DEBUGMODE
|
||||
else
|
||||
LFLAGS_LAST = -lalleg
|
||||
endif
|
||||
|
||||
ifdef MEMLEAK
|
||||
LFLAGS += -lpsapi
|
||||
endif
|
||||
|
||||
WITHICON = 1
|
||||
|
||||
######################################################################
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* ASE - Allegro Sprite Editor
|
||||
* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007,
|
||||
* 2008 David A. Capello
|
||||
* Copyright (C) 2001-2008 David A. 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* ASE - Allegro Sprite Editor
|
||||
* Copyright (C) 2001-2005, 2007, 2008 David A. Capello
|
||||
* Copyright (C) 2001-2008 David A. 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* ASE - Allegro Sprite Editor
|
||||
* Copyright (C) 2001-2005, 2007 David A. Capello
|
||||
* Copyright (C) 2001-2008 David A. 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* ASE - Allegro Sprite Editor
|
||||
* Copyright (C) 2001-2005, 2007 David A. Capello
|
||||
* Copyright (C) 2001-2008 David A. 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* ASE - Allegro Sprite Editor
|
||||
* Copyright (C) 2001-2005, 2007, 2008 David A. Capello
|
||||
* Copyright (C) 2001-2008 David A. 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
|
||||
@ -95,6 +95,7 @@ struct FileItem
|
||||
char *keyname;
|
||||
int attrib;
|
||||
#endif
|
||||
BITMAP *thumbnail;
|
||||
};
|
||||
|
||||
/* the root of the file-system */
|
||||
@ -275,11 +276,11 @@ bool fileitem_is_browsable(FileItem *fileitem)
|
||||
assert(fileitem->filename != NULL);
|
||||
|
||||
#ifdef USE_PIDLS
|
||||
return
|
||||
IS_FOLDER(fileitem) &&
|
||||
(fileitem->filename[0] != ':' ||
|
||||
/* My Computer = {20D04FE0-3AEA-1069-A2D8-08002B30309D} */
|
||||
ustrcmp(fileitem->filename, "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}") == 0);
|
||||
return IS_FOLDER(fileitem)
|
||||
&& (ustrcmp(get_extension(fileitem->filename), "zip") != 0)
|
||||
&& (fileitem->filename[0] != ':' ||
|
||||
/* My Computer = {20D04FE0-3AEA-1069-A2D8-08002B30309D} */
|
||||
ustrcmp(fileitem->filename, "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}") == 0);
|
||||
#else
|
||||
return IS_FOLDER(fileitem);
|
||||
#endif
|
||||
@ -439,6 +440,23 @@ bool fileitem_has_extension(FileItem *fileitem, const char *list_of_extensions)
|
||||
list_of_extensions);
|
||||
}
|
||||
|
||||
BITMAP *fileitem_get_thumbnail(FileItem *fileitem)
|
||||
{
|
||||
assert(fileitem != NULL);
|
||||
|
||||
return fileitem->thumbnail;
|
||||
}
|
||||
|
||||
void fileitem_set_thumbnail(FileItem *fileitem, BITMAP *thumbnail)
|
||||
{
|
||||
assert(fileitem != NULL);
|
||||
|
||||
if (fileitem->thumbnail)
|
||||
destroy_bitmap(fileitem->thumbnail);
|
||||
|
||||
fileitem->thumbnail = thumbnail;
|
||||
}
|
||||
|
||||
static FileItem *fileitem_new(FileItem *parent)
|
||||
{
|
||||
FileItem *fileitem = jnew(FileItem, 1);
|
||||
@ -458,6 +476,7 @@ static FileItem *fileitem_new(FileItem *parent)
|
||||
fileitem->keyname = NULL;
|
||||
fileitem->attrib = 0;
|
||||
#endif
|
||||
fileitem->thumbnail = NULL;
|
||||
|
||||
return fileitem;
|
||||
}
|
||||
@ -495,6 +514,9 @@ static void fileitem_free(FileItem *fileitem)
|
||||
if (fileitem->displayname)
|
||||
jfree(fileitem->displayname);
|
||||
|
||||
if (fileitem->thumbnail)
|
||||
destroy_bitmap(fileitem->thumbnail);
|
||||
|
||||
if (fileitem->children) {
|
||||
JLink link, next;
|
||||
JI_LIST_FOR_EACH_SAFE(fileitem->children, link, next) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* ASE - Allegro Sprite Editor
|
||||
* Copyright (C) 2008 David A. Capello
|
||||
* Copyright (C) 2001-2008 David A. 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
|
||||
@ -21,6 +21,7 @@
|
||||
|
||||
#include "jinete/jbase.h"
|
||||
|
||||
struct BITMAP;
|
||||
struct FileItem;
|
||||
typedef struct FileItem FileItem;
|
||||
|
||||
@ -42,5 +43,8 @@ JList fileitem_get_children(FileItem *fileitem);
|
||||
bool filename_has_extension(const char *filename, const char *list_of_extensions);
|
||||
bool fileitem_has_extension(FileItem *fileitem, const char *list_of_extensions);
|
||||
|
||||
struct BITMAP *fileitem_get_thumbnail(FileItem *fileitem);
|
||||
void fileitem_set_thumbnail(FileItem *fileitem, struct BITMAP *thumbnail);
|
||||
|
||||
#endif /* CORE_FILE_SYSTEM_H */
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* ASE - Allegro Sprite Editor
|
||||
* Copyright (C) 2001-2005, 2007, 2008 David A. Capello
|
||||
* Copyright (C) 2001-2008 David A. 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* ASE - Allegro Sprite Editor
|
||||
* Copyright (C) 2001-2005, 2007, 2008 David A. Capello
|
||||
* Copyright (C) 2001-2008 David A. 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* ASE - Allegro Sprite Editor
|
||||
* Copyright (C) 2001-2005, 2007, 2008 David A. Capello
|
||||
* Copyright (C) 2001-2008 David A. 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
|
||||
@ -29,6 +29,7 @@
|
||||
|
||||
#include "core/cfg.h"
|
||||
#include "core/dirs.h"
|
||||
#include "file/file.h"
|
||||
#include "modules/gfx.h"
|
||||
#include "modules/gui.h"
|
||||
#include "widgets/fileview.h"
|
||||
@ -40,7 +41,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef MAX_PATH
|
||||
# define MAX_PATH 4096
|
||||
# define MAX_PATH 4096 /* TODO this is needed for Linux, is it correct? */
|
||||
#endif
|
||||
|
||||
/* Variables used only to maintain the history of navigation. */
|
||||
@ -64,8 +65,11 @@ static bool fileview_msg_proc(JWidget widget, JMessage msg);
|
||||
static bool location_msg_proc(JWidget widget, JMessage msg);
|
||||
static bool filetype_msg_proc(JWidget widget, JMessage msg);
|
||||
|
||||
/**
|
||||
* The routine that shows the dialog to select a file in ASE.
|
||||
/* Shows the dialog to select a file in ASE.
|
||||
|
||||
Mainly it uses:
|
||||
* the 'core/file_system' routines.
|
||||
* the 'widgets/fileview' widget.
|
||||
*/
|
||||
char *ase_file_selector(const char *message,
|
||||
const char *init_path,
|
||||
@ -162,6 +166,8 @@ char *ase_file_selector(const char *message,
|
||||
jwidget_set_min_size(window, JI_SCREEN_W*9/10, JI_SCREEN_H*9/10);
|
||||
jwindow_remap(window);
|
||||
jwindow_center(window);
|
||||
|
||||
jwidget_add_tooltip_text(filetype, "hola\nchau");
|
||||
}
|
||||
else {
|
||||
fileview = jwidget_find_name(window, "fileview");
|
||||
@ -240,6 +246,7 @@ char *ase_file_selector(const char *message,
|
||||
}
|
||||
|
||||
/* TODO why this doesn't work if I remove this? */
|
||||
fileview_stop_threads(fileview);
|
||||
jwidget_free(window);
|
||||
window = NULL;
|
||||
|
||||
@ -431,6 +438,7 @@ static void goup_command(JWidget widget)
|
||||
fileview_goup(fileview);
|
||||
}
|
||||
|
||||
/* hook for the 'fileview' widget in the dialog */
|
||||
static bool fileview_msg_proc(JWidget widget, JMessage msg)
|
||||
{
|
||||
if (msg->type == JM_SIGNAL) {
|
||||
@ -450,10 +458,12 @@ static bool fileview_msg_proc(JWidget widget, JMessage msg)
|
||||
break;
|
||||
}
|
||||
|
||||
/* when a file is accepted */
|
||||
case SIGNAL_FILEVIEW_FILE_ACCEPT:
|
||||
jwidget_close_window(widget);
|
||||
break;
|
||||
|
||||
/* when the current folder change */
|
||||
case SIGNAL_FILEVIEW_CURRENT_FOLDER_CHANGED: {
|
||||
JWidget window = jwidget_get_window(widget);
|
||||
|
||||
@ -470,11 +480,14 @@ static bool fileview_msg_proc(JWidget widget, JMessage msg)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* hook for the 'location' combo-box */
|
||||
static bool location_msg_proc(JWidget widget, JMessage msg)
|
||||
{
|
||||
if (msg->type == JM_SIGNAL) {
|
||||
switch (msg->signal.num) {
|
||||
|
||||
|
||||
/* when the user change the location we have to set the
|
||||
current-folder in the 'fileview' widget */
|
||||
case JI_SIGNAL_COMBOBOX_SELECT: {
|
||||
FileItem *fileitem =
|
||||
jcombobox_get_data(widget,
|
||||
@ -485,6 +498,10 @@ static bool location_msg_proc(JWidget widget, JMessage msg)
|
||||
"fileview");
|
||||
|
||||
fileview_set_current_folder(fileview, fileitem);
|
||||
|
||||
/* refocus the 'fileview' (the focus in that widget is more
|
||||
useful for the user) */
|
||||
jmanager_set_focus(fileview);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -493,11 +510,14 @@ static bool location_msg_proc(JWidget widget, JMessage msg)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* hook for the 'filetype' combo-box */
|
||||
static bool filetype_msg_proc(JWidget widget, JMessage msg)
|
||||
{
|
||||
if (msg->type == JM_SIGNAL) {
|
||||
switch (msg->signal.num) {
|
||||
|
||||
/* when the user select a new file-type (extension), we have to
|
||||
change the file-extension in the 'filename' entry widget */
|
||||
case JI_SIGNAL_COMBOBOX_SELECT: {
|
||||
const char *ext = jcombobox_get_selected_string(widget);
|
||||
JWidget window = jwidget_get_window(widget);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* ASE - Allegro Sprite Editor
|
||||
* Copyright (C) 2001-2005, 2007, 2008 David A. Capello
|
||||
* Copyright (C) 2001-2008 David A. 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
|
||||
@ -72,6 +72,7 @@ ConvMatr *convmatr_new(int w, int h)
|
||||
if (!convmatr)
|
||||
return NULL;
|
||||
|
||||
convmatr->name = NULL;
|
||||
convmatr->w = w;
|
||||
convmatr->h = h;
|
||||
convmatr->cx = convmatr->w/2;
|
||||
@ -102,6 +103,9 @@ ConvMatr *convmatr_new_string(const char *format)
|
||||
|
||||
void convmatr_free(ConvMatr *convmatr)
|
||||
{
|
||||
if (convmatr->name)
|
||||
jfree(convmatr->name);
|
||||
|
||||
if (convmatr->data)
|
||||
jfree(convmatr->data);
|
||||
|
||||
|
@ -103,11 +103,6 @@ static void ase_file_write_cel_chunk(FILE *f, Cel *cel, Layer *layer, Sprite *sp
|
||||
static Mask *ase_file_read_mask_chunk(FILE *f);
|
||||
static void ase_file_write_mask_chunk(FILE *f, Mask *mask);
|
||||
|
||||
static int fgetw(FILE *file);
|
||||
static long fgetl(FILE *file);
|
||||
static int fputw(int w, FILE *file);
|
||||
static int fputl(long l, FILE *file);
|
||||
|
||||
FileFormat format_ase =
|
||||
{
|
||||
"ase,aseprite",
|
||||
@ -275,9 +270,16 @@ static bool load_ASE(FileOp *fop)
|
||||
}
|
||||
|
||||
fop->sprite = sprite;
|
||||
fclose(f);
|
||||
|
||||
return TRUE;
|
||||
if (ferror(f)) {
|
||||
fop_error(fop, _("Error reading file.\n"));
|
||||
fclose(f);
|
||||
return FALSE;
|
||||
}
|
||||
else {
|
||||
fclose(f);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static bool save_ASE(FileOp *fop)
|
||||
@ -333,8 +335,16 @@ static bool save_ASE(FileOp *fop)
|
||||
|
||||
/* write the header */
|
||||
ase_file_write_header(f, &header);
|
||||
fclose(f);
|
||||
return TRUE;
|
||||
|
||||
if (ferror(f)) {
|
||||
fop_error(fop, _("Error writing file.\n"));
|
||||
fclose(f);
|
||||
return FALSE;
|
||||
}
|
||||
else {
|
||||
fclose(f);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static bool ase_file_read_header(FILE *f, ASE_Header *header)
|
||||
@ -953,139 +963,3 @@ static void ase_file_write_mask_chunk(FILE *f, Mask *mask)
|
||||
|
||||
ase_file_write_close_chunk(f);
|
||||
}
|
||||
|
||||
/* returns a word (16 bits) */
|
||||
static int fgetw(FILE *file)
|
||||
{
|
||||
int b1, b2;
|
||||
|
||||
b1 = fgetc(file);
|
||||
if (b1 == EOF)
|
||||
return EOF;
|
||||
|
||||
b2 = fgetc(file);
|
||||
if (b2 == EOF)
|
||||
return EOF;
|
||||
|
||||
/* little endian */
|
||||
return ((b2 << 8) | b1);
|
||||
}
|
||||
|
||||
/* returns a dword (32 bits) */
|
||||
static long fgetl(FILE *file)
|
||||
{
|
||||
int b1, b2, b3, b4;
|
||||
|
||||
b1 = fgetc(file);
|
||||
if (b1 == EOF)
|
||||
return EOF;
|
||||
|
||||
b2 = fgetc(file);
|
||||
if (b2 == EOF)
|
||||
return EOF;
|
||||
|
||||
b3 = fgetc(file);
|
||||
if (b3 == EOF)
|
||||
return EOF;
|
||||
|
||||
b4 = fgetc(file);
|
||||
if (b4 == EOF)
|
||||
return EOF;
|
||||
|
||||
/* little endian */
|
||||
return ((b4 << 24) | (b3 << 16) | (b2 << 8) | b1);
|
||||
}
|
||||
|
||||
/* returns 0 in success or -1 in error */
|
||||
static int fputw(int w, FILE *file)
|
||||
{
|
||||
int b1, b2;
|
||||
|
||||
/* little endian */
|
||||
b2 = (w & 0xFF00) >> 8;
|
||||
b1 = w & 0x00FF;
|
||||
|
||||
if (fputc(b1, file) == b1)
|
||||
if (fputc(b2, file) == b2)
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* returns 0 in success or -1 in error */
|
||||
static int fputl(long l, FILE *file)
|
||||
{
|
||||
int b1, b2, b3, b4;
|
||||
|
||||
/* little endian */
|
||||
b4 = (int)((l & 0xFF000000L) >> 24);
|
||||
b3 = (int)((l & 0x00FF0000L) >> 16);
|
||||
b2 = (int)((l & 0x0000FF00L) >> 8);
|
||||
b1 = (int)l & 0x00FF;
|
||||
|
||||
if (fputc(b1, file) == b1)
|
||||
if (fputc(b2, file) == b2)
|
||||
if (fputc(b3, file) == b3)
|
||||
if (fputc(b4, file) == b4)
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* returns a floating point (32 bits) */
|
||||
static float fgetf(FILE *file)
|
||||
{
|
||||
union {
|
||||
float f;
|
||||
long l;
|
||||
} packet;
|
||||
|
||||
packet.l = fgetl(file);
|
||||
|
||||
return packet.f;
|
||||
}
|
||||
|
||||
/* returns a floating point with double precision (64 bits) */
|
||||
static double fgetd(FILE *file)
|
||||
{
|
||||
union {
|
||||
double d;
|
||||
long l[2];
|
||||
} packet;
|
||||
|
||||
packet.l[0] = fgetl(file);
|
||||
packet.l[1] = fgetl(file);
|
||||
|
||||
return packet.d;
|
||||
}
|
||||
|
||||
/* returns 0 in success or -1 in error */
|
||||
static int fputf(float c, FILE *file)
|
||||
{
|
||||
union {
|
||||
float f;
|
||||
long l;
|
||||
} packet;
|
||||
|
||||
packet.f = c;
|
||||
return fputl(packet.l, file);
|
||||
}
|
||||
|
||||
/* returns 0 in success or -1 in error */
|
||||
static int fputd(double c, FILE *file)
|
||||
{
|
||||
union {
|
||||
double d;
|
||||
long l[2];
|
||||
} packet;
|
||||
|
||||
packet.d = c;
|
||||
|
||||
if (fputl(packet.l[0], file) == 0)
|
||||
if (fputl(packet.l[1], file) == 0)
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
@ -23,7 +23,6 @@
|
||||
#ifndef USE_PRECOMPILED_HEADER
|
||||
|
||||
#include <allegro/color.h>
|
||||
#include <allegro/file.h>
|
||||
|
||||
#include "file/file.h"
|
||||
#include "raster/raster.h"
|
||||
@ -98,13 +97,13 @@ typedef struct OS2BMPINFOHEADER /* size: 12 */
|
||||
/* read_bmfileheader:
|
||||
* Reads a BMP file header and check that it has the BMP magic number.
|
||||
*/
|
||||
static int read_bmfileheader(PACKFILE *f, BITMAPFILEHEADER *fileheader)
|
||||
static int read_bmfileheader(FILE *f, BITMAPFILEHEADER *fileheader)
|
||||
{
|
||||
fileheader->bfType = pack_igetw(f);
|
||||
fileheader->bfSize= pack_igetl(f);
|
||||
fileheader->bfReserved1= pack_igetw(f);
|
||||
fileheader->bfReserved2= pack_igetw(f);
|
||||
fileheader->bfOffBits= pack_igetl(f);
|
||||
fileheader->bfType = fgetw(f);
|
||||
fileheader->bfSize= fgetl(f);
|
||||
fileheader->bfReserved1= fgetw(f);
|
||||
fileheader->bfReserved2= fgetw(f);
|
||||
fileheader->bfOffBits= fgetl(f);
|
||||
|
||||
if (fileheader->bfType != 19778)
|
||||
return -1;
|
||||
@ -115,20 +114,20 @@ static int read_bmfileheader(PACKFILE *f, BITMAPFILEHEADER *fileheader)
|
||||
/* read_win_bminfoheader:
|
||||
* Reads information from a BMP file header.
|
||||
*/
|
||||
static int read_win_bminfoheader(PACKFILE *f, BITMAPINFOHEADER *infoheader)
|
||||
static int read_win_bminfoheader(FILE *f, BITMAPINFOHEADER *infoheader)
|
||||
{
|
||||
WINBMPINFOHEADER win_infoheader;
|
||||
|
||||
win_infoheader.biWidth = pack_igetl(f);
|
||||
win_infoheader.biHeight = pack_igetl(f);
|
||||
win_infoheader.biPlanes = pack_igetw(f);
|
||||
win_infoheader.biBitCount = pack_igetw(f);
|
||||
win_infoheader.biCompression = pack_igetl(f);
|
||||
win_infoheader.biSizeImage = pack_igetl(f);
|
||||
win_infoheader.biXPelsPerMeter = pack_igetl(f);
|
||||
win_infoheader.biYPelsPerMeter = pack_igetl(f);
|
||||
win_infoheader.biClrUsed = pack_igetl(f);
|
||||
win_infoheader.biClrImportant = pack_igetl(f);
|
||||
win_infoheader.biWidth = fgetl(f);
|
||||
win_infoheader.biHeight = fgetl(f);
|
||||
win_infoheader.biPlanes = fgetw(f);
|
||||
win_infoheader.biBitCount = fgetw(f);
|
||||
win_infoheader.biCompression = fgetl(f);
|
||||
win_infoheader.biSizeImage = fgetl(f);
|
||||
win_infoheader.biXPelsPerMeter = fgetl(f);
|
||||
win_infoheader.biYPelsPerMeter = fgetl(f);
|
||||
win_infoheader.biClrUsed = fgetl(f);
|
||||
win_infoheader.biClrImportant = fgetl(f);
|
||||
|
||||
infoheader->biWidth = win_infoheader.biWidth;
|
||||
infoheader->biHeight = win_infoheader.biHeight;
|
||||
@ -141,14 +140,14 @@ static int read_win_bminfoheader(PACKFILE *f, BITMAPINFOHEADER *infoheader)
|
||||
/* read_os2_bminfoheader:
|
||||
* Reads information from an OS/2 format BMP file header.
|
||||
*/
|
||||
static int read_os2_bminfoheader(PACKFILE *f, BITMAPINFOHEADER *infoheader)
|
||||
static int read_os2_bminfoheader(FILE *f, BITMAPINFOHEADER *infoheader)
|
||||
{
|
||||
OS2BMPINFOHEADER os2_infoheader;
|
||||
|
||||
os2_infoheader.biWidth = pack_igetw(f);
|
||||
os2_infoheader.biHeight = pack_igetw(f);
|
||||
os2_infoheader.biPlanes = pack_igetw(f);
|
||||
os2_infoheader.biBitCount = pack_igetw(f);
|
||||
os2_infoheader.biWidth = fgetw(f);
|
||||
os2_infoheader.biHeight = fgetw(f);
|
||||
os2_infoheader.biPlanes = fgetw(f);
|
||||
os2_infoheader.biBitCount = fgetw(f);
|
||||
|
||||
infoheader->biWidth = os2_infoheader.biWidth;
|
||||
infoheader->biHeight = os2_infoheader.biHeight;
|
||||
@ -161,24 +160,24 @@ static int read_os2_bminfoheader(PACKFILE *f, BITMAPINFOHEADER *infoheader)
|
||||
/* read_bmicolors:
|
||||
* Loads the color palette for 1,4,8 bit formats.
|
||||
*/
|
||||
static void read_bmicolors(FileOp *fop, int ncols, PACKFILE *f,int win_flag)
|
||||
static void read_bmicolors(FileOp *fop, int ncols, FILE *f,int win_flag)
|
||||
{
|
||||
int i, r, g, b;
|
||||
|
||||
for (i=0; i<ncols; i++) {
|
||||
b = pack_getc(f) / 4;
|
||||
g = pack_getc(f) / 4;
|
||||
r = pack_getc(f) / 4;
|
||||
b = fgetc(f) / 4;
|
||||
g = fgetc(f) / 4;
|
||||
r = fgetc(f) / 4;
|
||||
fop_sequence_set_color(fop, i, r, g, b);
|
||||
if (win_flag)
|
||||
pack_getc(f);
|
||||
fgetc(f);
|
||||
}
|
||||
}
|
||||
|
||||
/* read_1bit_line:
|
||||
* Support function for reading the 1 bit bitmap file format.
|
||||
*/
|
||||
static void read_1bit_line(int length, PACKFILE *f, Image *image, int line)
|
||||
static void read_1bit_line(int length, FILE *f, Image *image, int line)
|
||||
{
|
||||
unsigned char b[32];
|
||||
unsigned long n;
|
||||
@ -188,7 +187,12 @@ static void read_1bit_line(int length, PACKFILE *f, Image *image, int line)
|
||||
for (i=0; i<length; i++) {
|
||||
j = i % 32;
|
||||
if (j == 0) {
|
||||
n = pack_mgetl(f);
|
||||
n = fgetl(f);
|
||||
n =
|
||||
((n&0x000000ff)<<24) |
|
||||
((n&0x0000ff00)<< 8) |
|
||||
((n&0x00ff0000)>> 8) |
|
||||
((n&0xff000000)>>24);
|
||||
for (k=0; k<32; k++) {
|
||||
b[31-k] = (char)(n & 1);
|
||||
n = n >> 1;
|
||||
@ -202,7 +206,7 @@ static void read_1bit_line(int length, PACKFILE *f, Image *image, int line)
|
||||
/* read_4bit_line:
|
||||
* Support function for reading the 4 bit bitmap file format.
|
||||
*/
|
||||
static void read_4bit_line(int length, PACKFILE *f, Image *image, int line)
|
||||
static void read_4bit_line(int length, FILE *f, Image *image, int line)
|
||||
{
|
||||
unsigned char b[8];
|
||||
unsigned long n;
|
||||
@ -213,7 +217,7 @@ static void read_4bit_line(int length, PACKFILE *f, Image *image, int line)
|
||||
for (i=0; i<length; i++) {
|
||||
j = i % 8;
|
||||
if (j == 0) {
|
||||
n = pack_igetl(f);
|
||||
n = fgetl(f);
|
||||
for (k=0; k<4; k++) {
|
||||
temp = n & 255;
|
||||
b[k*2+1] = temp & 15;
|
||||
@ -230,7 +234,7 @@ static void read_4bit_line(int length, PACKFILE *f, Image *image, int line)
|
||||
/* read_8bit_line:
|
||||
* Support function for reading the 8 bit bitmap file format.
|
||||
*/
|
||||
static void read_8bit_line(int length, PACKFILE *f, Image *image, int line)
|
||||
static void read_8bit_line(int length, FILE *f, Image *image, int line)
|
||||
{
|
||||
unsigned char b[4];
|
||||
unsigned long n;
|
||||
@ -240,7 +244,7 @@ static void read_8bit_line(int length, PACKFILE *f, Image *image, int line)
|
||||
for (i=0; i<length; i++) {
|
||||
j = i % 4;
|
||||
if (j == 0) {
|
||||
n = pack_igetl(f);
|
||||
n = fgetl(f);
|
||||
for (k=0; k<4; k++) {
|
||||
b[k] = (char)(n & 255);
|
||||
n = n >> 8;
|
||||
@ -255,7 +259,7 @@ static void read_8bit_line(int length, PACKFILE *f, Image *image, int line)
|
||||
* Support function for reading the 24 bit bitmap file format, doing
|
||||
* our best to convert it down to a 256 color palette.
|
||||
*/
|
||||
static void read_24bit_line(int length, PACKFILE *f, Image *image, int line)
|
||||
static void read_24bit_line(int length, FILE *f, Image *image, int line)
|
||||
{
|
||||
int i, nbytes;
|
||||
RGB c;
|
||||
@ -263,9 +267,9 @@ static void read_24bit_line(int length, PACKFILE *f, Image *image, int line)
|
||||
nbytes=0;
|
||||
|
||||
for (i=0; i<length; i++) {
|
||||
c.b = pack_getc(f);
|
||||
c.g = pack_getc(f);
|
||||
c.r = pack_getc(f);
|
||||
c.b = fgetc(f);
|
||||
c.g = fgetc(f);
|
||||
c.r = fgetc(f);
|
||||
image_putpixel(image, i, line, _rgba(c.r, c.g, c.b, 255));
|
||||
nbytes += 3;
|
||||
}
|
||||
@ -273,13 +277,13 @@ static void read_24bit_line(int length, PACKFILE *f, Image *image, int line)
|
||||
nbytes = nbytes % 4;
|
||||
if (nbytes != 0)
|
||||
for (i=nbytes; i<4; i++)
|
||||
pack_getc(f);
|
||||
fgetc(f);
|
||||
}
|
||||
|
||||
/* read_image:
|
||||
* For reading the noncompressed BMP image format.
|
||||
*/
|
||||
static void read_image(PACKFILE *f, Image *image, AL_CONST BITMAPINFOHEADER *infoheader, FileOp *fop)
|
||||
static void read_image(FILE *f, Image *image, AL_CONST BITMAPINFOHEADER *infoheader, FileOp *fop)
|
||||
{
|
||||
int i, line;
|
||||
|
||||
@ -306,13 +310,15 @@ static void read_image(PACKFILE *f, Image *image, AL_CONST BITMAPINFOHEADER *inf
|
||||
}
|
||||
|
||||
fop_progress(fop, (float)(i+1) / (float)(infoheader->biHeight));
|
||||
if (fop_is_stop(fop))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* read_RLE8_compressed_image:
|
||||
* For reading the 8 bit RLE compressed BMP image format.
|
||||
*/
|
||||
static void read_RLE8_compressed_image(PACKFILE *f, Image *image, AL_CONST BITMAPINFOHEADER *infoheader)
|
||||
static void read_RLE8_compressed_image(FILE *f, Image *image, AL_CONST BITMAPINFOHEADER *infoheader)
|
||||
{
|
||||
unsigned char count, val, val0;
|
||||
int j, pos, line;
|
||||
@ -326,8 +332,8 @@ static void read_RLE8_compressed_image(PACKFILE *f, Image *image, AL_CONST BITMA
|
||||
eolflag = 0; /* end of line flag */
|
||||
|
||||
while ((eolflag == 0) && (eopicflag == 0)) {
|
||||
count = pack_getc(f);
|
||||
val = pack_getc(f);
|
||||
count = fgetc(f);
|
||||
val = fgetc(f);
|
||||
|
||||
if (count > 0) { /* repeat pixel count times */
|
||||
for (j=0;j<count;j++) {
|
||||
@ -347,21 +353,21 @@ static void read_RLE8_compressed_image(PACKFILE *f, Image *image, AL_CONST BITMA
|
||||
break;
|
||||
|
||||
case 2: /* displace picture */
|
||||
count = pack_getc(f);
|
||||
val = pack_getc(f);
|
||||
count = fgetc(f);
|
||||
val = fgetc(f);
|
||||
pos += count;
|
||||
line -= val;
|
||||
break;
|
||||
|
||||
default: /* read in absolute mode */
|
||||
for (j=0; j<val; j++) {
|
||||
val0 = pack_getc(f);
|
||||
val0 = fgetc(f);
|
||||
image_putpixel(image, pos, line, val0);
|
||||
pos++;
|
||||
}
|
||||
|
||||
if (j%2 == 1)
|
||||
val0 = pack_getc(f); /* align on word boundary */
|
||||
val0 = fgetc(f); /* align on word boundary */
|
||||
break;
|
||||
|
||||
}
|
||||
@ -380,7 +386,7 @@ static void read_RLE8_compressed_image(PACKFILE *f, Image *image, AL_CONST BITMA
|
||||
/* read_RLE4_compressed_image:
|
||||
* For reading the 4 bit RLE compressed BMP image format.
|
||||
*/
|
||||
static void read_RLE4_compressed_image(PACKFILE *f, Image *image, AL_CONST BITMAPINFOHEADER *infoheader)
|
||||
static void read_RLE4_compressed_image(FILE *f, Image *image, AL_CONST BITMAPINFOHEADER *infoheader)
|
||||
{
|
||||
unsigned char b[8];
|
||||
unsigned char count;
|
||||
@ -396,8 +402,8 @@ static void read_RLE4_compressed_image(PACKFILE *f, Image *image, AL_CONST BITMA
|
||||
eolflag = 0; /* end of line flag */
|
||||
|
||||
while ((eolflag == 0) && (eopicflag == 0)) {
|
||||
count = pack_getc(f);
|
||||
val = pack_getc(f);
|
||||
count = fgetc(f);
|
||||
val = fgetc(f);
|
||||
|
||||
if (count > 0) { /* repeat pixels count times */
|
||||
b[1] = val & 15;
|
||||
@ -419,8 +425,8 @@ static void read_RLE4_compressed_image(PACKFILE *f, Image *image, AL_CONST BITMA
|
||||
break;
|
||||
|
||||
case 2: /* displace image */
|
||||
count = pack_getc(f);
|
||||
val = pack_getc(f);
|
||||
count = fgetc(f);
|
||||
val = fgetc(f);
|
||||
pos += count;
|
||||
line -= val;
|
||||
break;
|
||||
@ -428,7 +434,7 @@ static void read_RLE4_compressed_image(PACKFILE *f, Image *image, AL_CONST BITMA
|
||||
default: /* read in absolute mode */
|
||||
for (j=0; j<val; j++) {
|
||||
if ((j%4) == 0) {
|
||||
val0 = pack_igetw(f);
|
||||
val0 = fgetw(f);
|
||||
for (k=0; k<2; k++) {
|
||||
b[2*k+1] = val0 & 15;
|
||||
val0 = val0 >> 4;
|
||||
@ -453,7 +459,7 @@ static void read_RLE4_compressed_image(PACKFILE *f, Image *image, AL_CONST BITMA
|
||||
}
|
||||
}
|
||||
|
||||
static void read_bitfields_image(PACKFILE *f, Image *image, int bpp, BITMAPINFOHEADER *infoheader)
|
||||
static void read_bitfields_image(FILE *f, Image *image, int bpp, BITMAPINFOHEADER *infoheader)
|
||||
{
|
||||
int k, i;
|
||||
int bytesPerPixel;
|
||||
@ -467,7 +473,7 @@ static void read_bitfields_image(PACKFILE *f, Image *image, int bpp, BITMAPINFOH
|
||||
|
||||
for (i=0; i<(int)infoheader->biHeight; i++) {
|
||||
for (k=0; k<(int)infoheader->biWidth; k++) {
|
||||
pack_fread(&buffer, bytesPerPixel, f);
|
||||
fread(&buffer, 1, bytesPerPixel, f);
|
||||
|
||||
if (bpp == 15) {
|
||||
red = (buffer >> 10) & 0x1f;
|
||||
@ -503,25 +509,25 @@ static bool load_BMP(FileOp *fop)
|
||||
BITMAPFILEHEADER fileheader;
|
||||
BITMAPINFOHEADER infoheader;
|
||||
Image *image;
|
||||
PACKFILE *f;
|
||||
FILE *f;
|
||||
int ncol;
|
||||
unsigned long biSize;
|
||||
int type, bpp = 0;
|
||||
|
||||
f = pack_fopen(fop->filename, F_READ);
|
||||
f = fopen(fop->filename, "rb");
|
||||
if (!f)
|
||||
return FALSE;
|
||||
|
||||
if (read_bmfileheader(f, &fileheader) != 0) {
|
||||
pack_fclose(f);
|
||||
fclose(f);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
biSize = pack_igetl(f);
|
||||
biSize = fgetl(f);
|
||||
|
||||
if (biSize == WININFOHEADERSIZE) {
|
||||
if (read_win_bminfoheader(f, &infoheader) != 0) {
|
||||
pack_fclose(f);
|
||||
fclose(f);
|
||||
return FALSE;
|
||||
}
|
||||
/* compute number of colors recorded */
|
||||
@ -532,7 +538,7 @@ static bool load_BMP(FileOp *fop)
|
||||
}
|
||||
else if (biSize == OS2INFOHEADERSIZE) {
|
||||
if (read_os2_bminfoheader(f, &infoheader) != 0) {
|
||||
pack_fclose(f);
|
||||
fclose(f);
|
||||
return FALSE;
|
||||
}
|
||||
/* compute number of colors recorded */
|
||||
@ -542,7 +548,7 @@ static bool load_BMP(FileOp *fop)
|
||||
read_bmicolors(fop, ncol, f, 0);
|
||||
}
|
||||
else {
|
||||
pack_fclose(f);
|
||||
fclose(f);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -554,9 +560,9 @@ static bool load_BMP(FileOp *fop)
|
||||
if (infoheader.biCompression == BI_BITFIELDS) {
|
||||
unsigned long redMask, bluMask;
|
||||
|
||||
redMask = pack_igetl(f);
|
||||
pack_igetl(f);
|
||||
bluMask = pack_igetl(f);
|
||||
redMask = fgetl(f);
|
||||
fgetl(f);
|
||||
bluMask = fgetl(f);
|
||||
|
||||
if ((bluMask == 0x001f) && (redMask == 0x7C00))
|
||||
bpp = 15;
|
||||
@ -566,7 +572,7 @@ static bool load_BMP(FileOp *fop)
|
||||
bpp = 32;
|
||||
else {
|
||||
/* Unrecognised bit masks/depth */
|
||||
pack_fclose(f);
|
||||
fclose(f);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@ -575,7 +581,7 @@ static bool load_BMP(FileOp *fop)
|
||||
infoheader.biWidth,
|
||||
infoheader.biHeight);
|
||||
if (!image) {
|
||||
pack_fclose(f);
|
||||
fclose(f);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -603,18 +609,25 @@ static bool load_BMP(FileOp *fop)
|
||||
break;
|
||||
|
||||
default:
|
||||
pack_fclose(f);
|
||||
fclose(f);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pack_fclose(f);
|
||||
return TRUE;
|
||||
if (ferror(f)) {
|
||||
fop_error(fop, _("Error reading file.\n"));
|
||||
fclose(f);
|
||||
return FALSE;
|
||||
}
|
||||
else {
|
||||
fclose(f);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static bool save_BMP(FileOp *fop)
|
||||
{
|
||||
Image *image = fop->seq.image;
|
||||
PACKFILE *f;
|
||||
FILE *f;
|
||||
int bfSize;
|
||||
int biSizeImage;
|
||||
int bpp = (image->imgtype == IMAGE_RGB) ? 24 : 8;
|
||||
@ -632,52 +645,50 @@ static bool save_BMP(FileOp *fop)
|
||||
bfSize = 54 + biSizeImage; /* header + image data */
|
||||
}
|
||||
|
||||
f = pack_fopen(fop->filename, F_WRITE);
|
||||
f = fopen(fop->filename, "wb");
|
||||
if (!f) {
|
||||
fop_error(fop, _("Error creating file.\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*allegro_errno = 0;
|
||||
|
||||
/* file_header */
|
||||
pack_iputw(0x4D42, f); /* bfType ("BM") */
|
||||
pack_iputl(bfSize, f); /* bfSize */
|
||||
pack_iputw(0, f); /* bfReserved1 */
|
||||
pack_iputw(0, f); /* bfReserved2 */
|
||||
fputw(0x4D42, f); /* bfType ("BM") */
|
||||
fputl(bfSize, f); /* bfSize */
|
||||
fputw(0, f); /* bfReserved1 */
|
||||
fputw(0, f); /* bfReserved2 */
|
||||
|
||||
if (bpp == 8) /* bfOffBits */
|
||||
pack_iputl(54+256*4, f);
|
||||
if (bpp == 8) /* bfOffBits */
|
||||
fputl(54+256*4, f);
|
||||
else
|
||||
pack_iputl(54, f);
|
||||
fputl(54, f);
|
||||
|
||||
/* info_header */
|
||||
pack_iputl(40, f); /* biSize */
|
||||
pack_iputl(image->w, f); /* biWidth */
|
||||
pack_iputl(image->h, f); /* biHeight */
|
||||
pack_iputw(1, f); /* biPlanes */
|
||||
pack_iputw(bpp, f); /* biBitCount */
|
||||
pack_iputl(0, f); /* biCompression */
|
||||
pack_iputl(biSizeImage, f); /* biSizeImage */
|
||||
pack_iputl(0xB12, f); /* biXPelsPerMeter (0xB12 = 72 dpi) */
|
||||
pack_iputl(0xB12, f); /* biYPelsPerMeter */
|
||||
fputl(40, f); /* biSize */
|
||||
fputl(image->w, f); /* biWidth */
|
||||
fputl(image->h, f); /* biHeight */
|
||||
fputw(1, f); /* biPlanes */
|
||||
fputw(bpp, f); /* biBitCount */
|
||||
fputl(0, f); /* biCompression */
|
||||
fputl(biSizeImage, f); /* biSizeImage */
|
||||
fputl(0xB12, f); /* biXPelsPerMeter (0xB12 = 72 dpi) */
|
||||
fputl(0xB12, f); /* biYPelsPerMeter */
|
||||
|
||||
if (bpp == 8) {
|
||||
pack_iputl(256, f); /* biClrUsed */
|
||||
pack_iputl(256, f); /* biClrImportant */
|
||||
fputl(256, f); /* biClrUsed */
|
||||
fputl(256, f); /* biClrImportant */
|
||||
|
||||
/* palette */
|
||||
for (i=0; i<256; i++) {
|
||||
fop_sequence_get_color(fop, i, &r, &g, &b);
|
||||
pack_putc(_rgb_scale_6[b], f);
|
||||
pack_putc(_rgb_scale_6[g], f);
|
||||
pack_putc(_rgb_scale_6[r], f);
|
||||
pack_putc(0, f);
|
||||
fputc(_rgb_scale_6[b], f);
|
||||
fputc(_rgb_scale_6[g], f);
|
||||
fputc(_rgb_scale_6[r], f);
|
||||
fputc(0, f);
|
||||
}
|
||||
}
|
||||
else {
|
||||
pack_iputl(0, f); /* biClrUsed */
|
||||
pack_iputl(0, f); /* biClrImportant */
|
||||
fputl(0, f); /* biClrUsed */
|
||||
fputl(0, f); /* biClrImportant */
|
||||
}
|
||||
|
||||
/* image data */
|
||||
@ -685,30 +696,31 @@ static bool save_BMP(FileOp *fop)
|
||||
for (j=0; j<image->w; j++) {
|
||||
if (bpp == 8) {
|
||||
if (image->imgtype == IMAGE_INDEXED)
|
||||
pack_putc(image->method->getpixel(image, j, i), f);
|
||||
fputc(image->method->getpixel(image, j, i), f);
|
||||
else if (image->imgtype == IMAGE_GRAYSCALE)
|
||||
pack_putc(_graya_getk(image->method->getpixel(image, j, i)), f);
|
||||
fputc(_graya_getk(image->method->getpixel(image, j, i)), f);
|
||||
}
|
||||
else {
|
||||
c = image->method->getpixel(image, j, i);
|
||||
pack_putc(_rgba_getb(c), f);
|
||||
pack_putc(_rgba_getg(c), f);
|
||||
pack_putc(_rgba_getr(c), f);
|
||||
fputc(_rgba_getb(c), f);
|
||||
fputc(_rgba_getg(c), f);
|
||||
fputc(_rgba_getr(c), f);
|
||||
}
|
||||
}
|
||||
|
||||
for (j=0; j<filler; j++)
|
||||
pack_putc(0, f);
|
||||
fputc(0, f);
|
||||
|
||||
fop_progress(fop, (float)(image->h-i) / (float)image->h);
|
||||
}
|
||||
|
||||
pack_fclose(f);
|
||||
|
||||
if (*allegro_errno) {
|
||||
fop_error(fop, _("Error writing bytes.\n"));
|
||||
if (ferror(f)) {
|
||||
fop_error(fop, _("Error writing file.\n"));
|
||||
fclose(f);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
else {
|
||||
fclose(f);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
206
src/file/file.c
206
src/file/file.c
@ -1,5 +1,5 @@
|
||||
/* ASE - Allegro Sprite Editor
|
||||
* Copyright (C) 2001-2005, 2007, 2008 David A. Capello
|
||||
* Copyright (C) 2001-2008 David A. 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
|
||||
@ -106,12 +106,14 @@ void get_writable_extensions(char *buf, int size)
|
||||
Sprite *sprite_load(const char *filename)
|
||||
{
|
||||
Sprite *sprite;
|
||||
FileOp *fop = fop_to_load_sprite(filename);
|
||||
/* TODO add a option to configure what to do with the sequence */
|
||||
FileOp *fop = fop_to_load_sprite(filename, FILE_LOAD_SEQUENCE_NONE);
|
||||
if (!fop)
|
||||
return NULL;
|
||||
|
||||
/* operate in this same thread */
|
||||
fop_operate(fop);
|
||||
fop_done(fop);
|
||||
|
||||
if (fop->error)
|
||||
console_printf(fop->error);
|
||||
@ -131,6 +133,7 @@ int sprite_save(Sprite *sprite)
|
||||
|
||||
/* operate in this same thread */
|
||||
fop_operate(fop);
|
||||
fop_done(fop);
|
||||
|
||||
if (fop->error)
|
||||
console_printf(fop->error);
|
||||
@ -141,7 +144,7 @@ int sprite_save(Sprite *sprite)
|
||||
return ret;
|
||||
}
|
||||
|
||||
FileOp *fop_to_load_sprite(const char *filename)
|
||||
FileOp *fop_to_load_sprite(const char *filename, int flags)
|
||||
{
|
||||
char *extension;
|
||||
FileOp *fop;
|
||||
@ -172,51 +175,56 @@ FileOp *fop_to_load_sprite(const char *filename)
|
||||
|
||||
/* use the "sequence" interface */
|
||||
if (fop->format->flags & FILE_SUPPORT_SEQUENCES) {
|
||||
char buf[512], left[512], right[512];
|
||||
int c, width, start_from;
|
||||
|
||||
/* prepare to load a sequence */
|
||||
fop_prepare_for_sequence(fop);
|
||||
|
||||
/* first of all, we must generate the list of files to load in the
|
||||
sequence... */
|
||||
|
||||
/* per now, we want load just one file */
|
||||
jlist_append(fop->seq.filename_list, jstrdup(filename));
|
||||
|
||||
/* check is this could be a sequence */
|
||||
start_from = split_filename(filename, left, right, &width);
|
||||
if (start_from >= 0) {
|
||||
/* try to get more file names */
|
||||
for (c=start_from+1; ; c++) {
|
||||
/* get the next file name */
|
||||
usprintf(buf, "%s%0*d%s", left, width, c, right);
|
||||
/* don't load the sequence (just the one file/one frame) */
|
||||
if (!(flags & FILE_LOAD_SEQUENCE_NONE)) {
|
||||
char buf[512], left[512], right[512];
|
||||
int c, width, start_from;
|
||||
|
||||
/* if the file doesn't exist, we doesn't need more files to load */
|
||||
if (!exists(buf))
|
||||
break;
|
||||
/* first of all, we must generate the list of files to load in the
|
||||
sequence... */
|
||||
|
||||
/* add this file name to the list */
|
||||
jlist_append(fop->seq.filename_list,
|
||||
jstrdup(buf));
|
||||
/* check is this could be a sequence */
|
||||
start_from = split_filename(filename, left, right, &width);
|
||||
if (start_from >= 0) {
|
||||
/* try to get more file names */
|
||||
for (c=start_from+1; ; c++) {
|
||||
/* get the next file name */
|
||||
usprintf(buf, "%s%0*d%s", left, width, c, right);
|
||||
|
||||
/* if the file doesn't exist, we doesn't need more files to load */
|
||||
if (!exists(buf))
|
||||
break;
|
||||
|
||||
/* add this file name to the list */
|
||||
jlist_append(fop->seq.filename_list,
|
||||
jstrdup(buf));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO add a better dialog to edit file-names */
|
||||
if (is_interactive()) {
|
||||
/* really want load all files? */
|
||||
if ((jlist_length(fop->seq.filename_list) > 1) &&
|
||||
(jalert(_("Notice"
|
||||
"<<Possible animation with:"
|
||||
"<<%s"
|
||||
"<<Load the sequence of bitmaps?"
|
||||
"||&Agree||&Skip"),
|
||||
get_filename(filename)) != 1)) {
|
||||
/* if the user replies "Skip", we need just one file name (the
|
||||
first one) */
|
||||
while (jlist_length(fop->seq.filename_list) > 1) {
|
||||
JLink link = jlist_last(fop->seq.filename_list);
|
||||
jfree(link->data);
|
||||
jlist_delete_link(fop->seq.filename_list, link);
|
||||
/* TODO add a better dialog to edit file-names */
|
||||
if ((flags & FILE_LOAD_SEQUENCE_ASK) &&
|
||||
is_interactive()) {
|
||||
/* really want load all files? */
|
||||
if ((jlist_length(fop->seq.filename_list) > 1) &&
|
||||
(jalert(_("Notice"
|
||||
"<<Possible animation with:"
|
||||
"<<%s"
|
||||
"<<Load the sequence of bitmaps?"
|
||||
"||&Agree||&Skip"),
|
||||
get_filename(filename)) != 1)) {
|
||||
/* if the user replies "Skip", we need just one file name (the
|
||||
first one) */
|
||||
while (jlist_length(fop->seq.filename_list) > 1) {
|
||||
JLink link = jlist_last(fop->seq.filename_list);
|
||||
jfree(link->data);
|
||||
jlist_delete_link(fop->seq.filename_list, link);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -224,6 +232,10 @@ FileOp *fop_to_load_sprite(const char *filename)
|
||||
else
|
||||
fop->filename = jstrdup(filename);
|
||||
|
||||
/* load just one frame */
|
||||
if (flags & FILE_LOAD_ONE_FRAME)
|
||||
fop->oneframe = TRUE;
|
||||
|
||||
done:;
|
||||
jfree(extension);
|
||||
return fop;
|
||||
@ -414,7 +426,7 @@ FileOp *fop_to_save_sprite(Sprite *sprite)
|
||||
* It can be called from a different thread of the one used
|
||||
* by @ref fop_to_load_sprite or @ref fop_to_save_sprite.
|
||||
*
|
||||
* After operate you must to free the 'fop' calling @ref fop_free.
|
||||
* After operate you must to mark the 'fop' as 'done' using @ref fop_done.
|
||||
*/
|
||||
void fop_operate(FileOp *fop)
|
||||
{
|
||||
@ -617,6 +629,15 @@ void fop_operate(FileOp *fop)
|
||||
}
|
||||
}
|
||||
|
||||
/* progress = 100% */
|
||||
fop_progress(fop, 1.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* After mark the 'fop' as 'done' you must to free it calling @ref fop_free.
|
||||
*/
|
||||
void fop_done(FileOp *fop)
|
||||
{
|
||||
/* finally done */
|
||||
jmutex_lock(fop->mutex);
|
||||
{
|
||||
@ -625,6 +646,16 @@ void fop_operate(FileOp *fop)
|
||||
jmutex_unlock(fop->mutex);
|
||||
}
|
||||
|
||||
void fop_stop(FileOp *fop)
|
||||
{
|
||||
jmutex_lock(fop->mutex);
|
||||
{
|
||||
if (!fop->done)
|
||||
fop->stop = TRUE;
|
||||
}
|
||||
jmutex_unlock(fop->mutex);
|
||||
}
|
||||
|
||||
void fop_free(FileOp *fop)
|
||||
{
|
||||
if (fop->filename)
|
||||
@ -814,14 +845,16 @@ static FileOp *fop_new(FileOpType type)
|
||||
return NULL;
|
||||
|
||||
fop->type = type;
|
||||
fop->format = NULL;
|
||||
fop->sprite = NULL;
|
||||
fop->error = NULL;
|
||||
fop->filename = NULL;
|
||||
|
||||
fop->mutex = jmutex_new();
|
||||
fop->progress = 0.0f;
|
||||
fop->error = NULL;
|
||||
fop->done = FALSE;
|
||||
fop->stop = FALSE;
|
||||
fop->oneframe = FALSE;
|
||||
|
||||
fop->seq.filename_list = NULL;
|
||||
fop->seq.palette = NULL;
|
||||
@ -925,3 +958,94 @@ static int split_filename(const char *filename, char *left, char *right, int *wi
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads a WORD (16 bits) using in little-endian byte ordering.
|
||||
*/
|
||||
int fgetw(FILE *file)
|
||||
{
|
||||
int b1, b2;
|
||||
|
||||
b1 = fgetc(file);
|
||||
if (b1 == EOF)
|
||||
return EOF;
|
||||
|
||||
b2 = fgetc(file);
|
||||
if (b2 == EOF)
|
||||
return EOF;
|
||||
|
||||
/* little endian */
|
||||
return ((b2 << 8) | b1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a DWORD (32 bits) using in little-endian byte ordering.
|
||||
*/
|
||||
long fgetl(FILE *file)
|
||||
{
|
||||
int b1, b2, b3, b4;
|
||||
|
||||
b1 = fgetc(file);
|
||||
if (b1 == EOF)
|
||||
return EOF;
|
||||
|
||||
b2 = fgetc(file);
|
||||
if (b2 == EOF)
|
||||
return EOF;
|
||||
|
||||
b3 = fgetc(file);
|
||||
if (b3 == EOF)
|
||||
return EOF;
|
||||
|
||||
b4 = fgetc(file);
|
||||
if (b4 == EOF)
|
||||
return EOF;
|
||||
|
||||
/* little endian */
|
||||
return ((b4 << 24) | (b3 << 16) | (b2 << 8) | b1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a word using in little-endian byte ordering.
|
||||
*
|
||||
* @return 0 in success or -1 in error
|
||||
*/
|
||||
int fputw(int w, FILE *file)
|
||||
{
|
||||
int b1, b2;
|
||||
|
||||
/* little endian */
|
||||
b2 = (w & 0xFF00) >> 8;
|
||||
b1 = w & 0x00FF;
|
||||
|
||||
if (fputc(b1, file) == b1)
|
||||
if (fputc(b2, file) == b2)
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes DWORD a using in little-endian byte ordering.
|
||||
*
|
||||
* @return 0 in success or -1 in error
|
||||
*/
|
||||
int fputl(long l, FILE *file)
|
||||
{
|
||||
int b1, b2, b3, b4;
|
||||
|
||||
/* little endian */
|
||||
b4 = (int)((l & 0xFF000000L) >> 24);
|
||||
b3 = (int)((l & 0x00FF0000L) >> 16);
|
||||
b2 = (int)((l & 0x0000FF00L) >> 8);
|
||||
b1 = (int)l & 0x00FF;
|
||||
|
||||
if (fputc(b1, file) == b1)
|
||||
if (fputc(b2, file) == b2)
|
||||
if (fputc(b3, file) == b3)
|
||||
if (fputc(b4, file) == b4)
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* ASE - Allegro Sprite Editor
|
||||
* Copyright (C) 2001-2005, 2007, 2008 David A. Capello
|
||||
* Copyright (C) 2001-2008 David A. 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
|
||||
@ -21,6 +21,7 @@
|
||||
|
||||
#include "jinete/jbase.h"
|
||||
#include <allegro/color.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define FILE_SUPPORT_RGB (1<<0)
|
||||
#define FILE_SUPPORT_RGBA (1<<1)
|
||||
@ -34,6 +35,11 @@
|
||||
#define FILE_SUPPORT_MASKS_REPOSITORY (1<<9)
|
||||
#define FILE_SUPPORT_PATHS_REPOSITORY (1<<10)
|
||||
|
||||
#define FILE_LOAD_SEQUENCE_NONE (1<<0)
|
||||
#define FILE_LOAD_SEQUENCE_ASK (1<<1)
|
||||
#define FILE_LOAD_SEQUENCE_YES (1<<2)
|
||||
#define FILE_LOAD_ONE_FRAME (1<<3)
|
||||
|
||||
struct Image;
|
||||
struct Cel;
|
||||
struct Layer;
|
||||
@ -71,6 +77,9 @@ typedef struct FileOp
|
||||
char *error; /* error string */
|
||||
bool done : 1; /* true if the operation finished */
|
||||
bool stop : 1; /* force the break of the operation */
|
||||
bool oneframe : 1; /* load just one frame (in formats
|
||||
that support animation like
|
||||
GIF/FLI/ASE) */
|
||||
|
||||
/* data for sequences */
|
||||
struct {
|
||||
@ -99,9 +108,11 @@ int sprite_save(struct Sprite *sprite);
|
||||
|
||||
/* low-level routines to load/save sprites */
|
||||
|
||||
FileOp *fop_to_load_sprite(const char *filename);
|
||||
FileOp *fop_to_load_sprite(const char *filename, int flags);
|
||||
FileOp *fop_to_save_sprite(struct Sprite *sprite);
|
||||
void fop_operate(FileOp *fop);
|
||||
void fop_done(FileOp *fop);
|
||||
void fop_stop(FileOp *fop);
|
||||
void fop_free(FileOp *fop);
|
||||
|
||||
void fop_sequence_set_color(FileOp *fop, int index, int r, int g, int b);
|
||||
@ -115,4 +126,9 @@ float fop_get_progress(FileOp *fop);
|
||||
bool fop_is_done(FileOp *fop);
|
||||
bool fop_is_stop(FileOp *fop);
|
||||
|
||||
int fgetw(FILE *file);
|
||||
long fgetl(FILE *file);
|
||||
int fputw(int w, FILE *file);
|
||||
int fputl(long l, FILE *file);
|
||||
|
||||
#endif /* FILE_H */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* ASE - Allegro Sprite Editor
|
||||
* Copyright (C) 2001-2005, 2007, 2008 David A. Capello
|
||||
* Copyright (C) 2001-2008 David A. 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
|
||||
@ -64,8 +64,7 @@ static bool load_FLI(FileOp *fop)
|
||||
unsigned char cmap[768];
|
||||
unsigned char omap[768];
|
||||
s_fli_header fli_header;
|
||||
bool inc_frpos_out;
|
||||
Image *bmp, *old;
|
||||
Image *bmp, *old, *image;
|
||||
Sprite *sprite;
|
||||
Layer *layer;
|
||||
PALETTE pal;
|
||||
@ -73,6 +72,7 @@ static bool load_FLI(FileOp *fop)
|
||||
int frpos_in;
|
||||
int frpos_out;
|
||||
int index = 0;
|
||||
Cel *cel;
|
||||
FILE *f;
|
||||
|
||||
/* open the file to read in binary mode */
|
||||
@ -83,6 +83,12 @@ static bool load_FLI(FileOp *fop)
|
||||
fli_read_header(f, &fli_header);
|
||||
fseek(f, 128, SEEK_SET);
|
||||
|
||||
if (fli_header.magic == NO_HEADER) {
|
||||
fop_error(fop, _("The file doesn't have a FLIC header\n"));
|
||||
fclose(f);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* size by frame */
|
||||
w = fli_header.width;
|
||||
h = fli_header.height;
|
||||
@ -91,7 +97,7 @@ static bool load_FLI(FileOp *fop)
|
||||
bmp = image_new(IMAGE_INDEXED, w, h);
|
||||
old = image_new(IMAGE_INDEXED, w, h);
|
||||
if ((!bmp) || (!old)) {
|
||||
fop_error(fop, _("Not enough memory for temporary bitmaps.\n"));
|
||||
fop_error(fop, _("Not enough memory.\n"));
|
||||
if (bmp) image_free(bmp);
|
||||
if (old) image_free(old);
|
||||
fclose(f);
|
||||
@ -109,8 +115,6 @@ static bool load_FLI(FileOp *fop)
|
||||
sprite_set_speed(sprite, fli_header.speed);
|
||||
|
||||
/* write frame by frame */
|
||||
inc_frpos_out = FALSE;
|
||||
|
||||
for (frpos_in=frpos_out=0;
|
||||
frpos_in<sprite->frames;
|
||||
frpos_in++) {
|
||||
@ -119,28 +123,58 @@ static bool load_FLI(FileOp *fop)
|
||||
(unsigned char *)old->dat, omap,
|
||||
(unsigned char *)bmp->dat, cmap);
|
||||
|
||||
/* first frame or the frames changes */
|
||||
if ((frpos_in == 0) || (image_count_diff(old, bmp))) {
|
||||
/* first frame, or the frames changes, or the palette changes */
|
||||
if ((frpos_in == 0) ||
|
||||
(image_count_diff(old, bmp))
|
||||
#ifndef USE_LINK /* TODO this should be configurable through a check-box */
|
||||
|| (memcmp(omap, cmap, 768) != 0)
|
||||
#endif
|
||||
) {
|
||||
/* the image changes? */
|
||||
if (frpos_in != 0)
|
||||
frpos_out++;
|
||||
|
||||
/* add the new frame */
|
||||
index = stock_add_image(sprite->stock, image_new_copy(bmp));
|
||||
layer_add_cel(layer, cel_new(frpos_out, index));
|
||||
image = image_new_copy(bmp);
|
||||
if (!image) {
|
||||
fop_error(fop, _("Not enough memory\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
index = stock_add_image(sprite->stock, image);
|
||||
if (index < 0) {
|
||||
image_free(image);
|
||||
fop_error(fop, _("Not enough memory\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
cel = cel_new(frpos_out, index);
|
||||
if (!cel) {
|
||||
fop_error(fop, _("Not enough memory\n"));
|
||||
break;
|
||||
}
|
||||
layer_add_cel(layer, cel);
|
||||
|
||||
/* first frame or the palette changes */
|
||||
if ((frpos_in == 0) || (memcmp(omap, cmap, 768) != 0))
|
||||
SETPAL();
|
||||
}
|
||||
#ifdef USE_LINK
|
||||
/* the palette changes */
|
||||
else if (memcmp(omap, cmap, 768) != 0) {
|
||||
frpos_out++;
|
||||
SETPAL();
|
||||
|
||||
/* add link */
|
||||
layer_add_cel(layer, cel_new(frpos_out, index));
|
||||
cel = cel_new(frpos_out, index);
|
||||
if (!cel) {
|
||||
fop_error(fop, _("Not enough memory\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
layer_add_cel(layer, cel);
|
||||
}
|
||||
#endif
|
||||
/* the palette and the image don't change: add duration to the last added frame */
|
||||
else {
|
||||
sprite_set_frlen(sprite,
|
||||
@ -154,6 +188,12 @@ static bool load_FLI(FileOp *fop)
|
||||
|
||||
/* update progress */
|
||||
fop_progress(fop, (float)(frpos_in+1) / (float)(sprite->frames));
|
||||
if (fop_is_stop(fop))
|
||||
break;
|
||||
|
||||
/* just one frame? */
|
||||
if (fop->oneframe)
|
||||
break;
|
||||
}
|
||||
|
||||
/* update sprites frames */
|
||||
|
@ -1,11 +1,13 @@
|
||||
#include <allegro.h>
|
||||
|
||||
#include "format.h"
|
||||
#include "lzw.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <allegro.h>
|
||||
|
||||
#include "file/gif/format.h"
|
||||
#include "file/gif/lzw.h"
|
||||
#include "file/file.h"
|
||||
|
||||
GIF_ANIMATION *
|
||||
gif_create_animation(int frames_count)
|
||||
{
|
||||
@ -24,37 +26,37 @@ gif_destroy_animation (GIF_ANIMATION *gif)
|
||||
|
||||
for (i = 0; i < gif->frames_count; i++)
|
||||
{
|
||||
GIF_FRAME *frame = gif->frames + i;
|
||||
GIF_FRAME *frame = gif->frames + i;
|
||||
|
||||
if (frame->bitmap_8_bit)
|
||||
free (frame->bitmap_8_bit);
|
||||
if (frame->bitmap_8_bit)
|
||||
free (frame->bitmap_8_bit);
|
||||
}
|
||||
free (gif->frames);
|
||||
free (gif);
|
||||
}
|
||||
|
||||
static void
|
||||
write_palette (PACKFILE *file, GIF_PALETTE *palette, int bits)
|
||||
write_palette (FILE *file, GIF_PALETTE *palette, int bits)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < (1 << bits); i++)
|
||||
{
|
||||
pack_putc (palette->colors[i].r, file);
|
||||
pack_putc (palette->colors[i].g, file);
|
||||
pack_putc (palette->colors[i].b, file);
|
||||
fputc (palette->colors[i].r, file);
|
||||
fputc (palette->colors[i].g, file);
|
||||
fputc (palette->colors[i].b, file);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
read_palette (PACKFILE * file, GIF_PALETTE *palette)
|
||||
read_palette (FILE * file, GIF_PALETTE *palette)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < palette->colors_count; i++)
|
||||
{
|
||||
palette->colors[i].r = pack_getc (file);
|
||||
palette->colors[i].g = pack_getc (file);
|
||||
palette->colors[i].b = pack_getc (file);
|
||||
palette->colors[i].r = fgetc (file);
|
||||
palette->colors[i].g = fgetc (file);
|
||||
palette->colors[i].b = fgetc (file);
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,92 +93,92 @@ gif_save_animation (const char *filename, GIF_ANIMATION *gif,
|
||||
{
|
||||
int frame;
|
||||
int i, j;
|
||||
PACKFILE *file;
|
||||
FILE *file;
|
||||
|
||||
file = pack_fopen (filename, "w");
|
||||
file = fopen (filename, "wb");
|
||||
if (!file)
|
||||
return -1;
|
||||
return -1;
|
||||
|
||||
pack_fwrite ("GIF89a", 6, file);
|
||||
pack_iputw (gif->width, file);
|
||||
pack_iputw (gif->height, file);
|
||||
fwrite ("GIF89a", 1, 6, file);
|
||||
fputw (gif->width, file);
|
||||
fputw (gif->height, file);
|
||||
/* 7 global palette
|
||||
* 456 color richness
|
||||
* 3 sorted
|
||||
* 012 palette bits
|
||||
*/
|
||||
for (i = 1, j = 0; i < gif->palette.colors_count; i *= 2, j++);
|
||||
pack_putc ((j ? 128 : 0) + 64 + 32 + 16 + (j ? j - 1 : 0), file);
|
||||
pack_putc (gif->background_index, file);
|
||||
pack_putc (0, file); /* No aspect ratio. */
|
||||
fputc ((j ? 128 : 0) + 64 + 32 + 16 + (j ? j - 1 : 0), file);
|
||||
fputc (gif->background_index, file);
|
||||
fputc (0, file); /* No aspect ratio. */
|
||||
|
||||
if (j)
|
||||
write_palette (file, &gif->palette, j);
|
||||
write_palette (file, &gif->palette, j);
|
||||
|
||||
if (gif->loop != -1)
|
||||
/* Loop count extension. */
|
||||
{
|
||||
pack_putc (0x21, file); /* Extension Introducer. */
|
||||
pack_putc (0xff, file); /* Application Extension. */
|
||||
pack_putc (11, file); /* Size. */
|
||||
pack_fwrite ("NETSCAPE2.0", 11, file);
|
||||
pack_putc (3, file); /* Size. */
|
||||
pack_putc (1, file);
|
||||
pack_iputw (gif->loop, file);
|
||||
pack_putc (0, file);
|
||||
fputc (0x21, file); /* Extension Introducer. */
|
||||
fputc (0xff, file); /* Application Extension. */
|
||||
fputc (11, file); /* Size. */
|
||||
fwrite ("NETSCAPE2.0", 1, 11, file);
|
||||
fputc (3, file); /* Size. */
|
||||
fputc (1, file);
|
||||
fputw (gif->loop, file);
|
||||
fputc (0, file);
|
||||
}
|
||||
|
||||
progress(dp, 0.0f);
|
||||
for (frame = 0; frame < gif->frames_count; frame++)
|
||||
{
|
||||
int w = gif->frames[frame].w;
|
||||
int h = gif->frames[frame].h;
|
||||
int w = gif->frames[frame].w;
|
||||
int h = gif->frames[frame].h;
|
||||
|
||||
pack_putc (0x21, file); /* Extension Introducer. */
|
||||
pack_putc (0xf9, file); /* Graphic Control Extension. */
|
||||
pack_putc (4, file); /* Size. */
|
||||
/* Disposal method, and enable transparency. */
|
||||
i = gif->frames[frame].disposal_method << 2;
|
||||
if (gif->frames[frame].transparent_index != -1)
|
||||
i |= 1;
|
||||
pack_putc (i, file);
|
||||
pack_iputw (gif->frames[frame].duration, file); /* In 1/100th seconds. */
|
||||
if (gif->frames[frame].transparent_index != -1)
|
||||
pack_putc (gif->frames[frame].transparent_index, file); /* Transparent color index. */
|
||||
else
|
||||
pack_putc (0, file);
|
||||
pack_putc (0x00, file); /* Terminator. */
|
||||
fputc (0x21, file); /* Extension Introducer. */
|
||||
fputc (0xf9, file); /* Graphic Control Extension. */
|
||||
fputc (4, file); /* Size. */
|
||||
/* Disposal method, and enable transparency. */
|
||||
i = gif->frames[frame].disposal_method << 2;
|
||||
if (gif->frames[frame].transparent_index != -1)
|
||||
i |= 1;
|
||||
fputc (i, file);
|
||||
fputw (gif->frames[frame].duration, file); /* In 1/100th seconds. */
|
||||
if (gif->frames[frame].transparent_index != -1)
|
||||
fputc (gif->frames[frame].transparent_index, file); /* Transparent color index. */
|
||||
else
|
||||
fputc (0, file);
|
||||
fputc (0x00, file); /* Terminator. */
|
||||
|
||||
pack_putc (0x2c, file); /* Image Descriptor. */
|
||||
pack_iputw (gif->frames[frame].xoff, file);
|
||||
pack_iputw (gif->frames[frame].yoff, file);
|
||||
pack_iputw (w, file);
|
||||
pack_iputw (h, file);
|
||||
fputc (0x2c, file); /* Image Descriptor. */
|
||||
fputw (gif->frames[frame].xoff, file);
|
||||
fputw (gif->frames[frame].yoff, file);
|
||||
fputw (w, file);
|
||||
fputw (h, file);
|
||||
|
||||
/* 7: local palette
|
||||
* 6: interlaced
|
||||
* 5: sorted
|
||||
* 012: palette bits
|
||||
*/
|
||||
/* 7: local palette
|
||||
* 6: interlaced
|
||||
* 5: sorted
|
||||
* 012: palette bits
|
||||
*/
|
||||
|
||||
for (i = 1, j = 0; i < gif->frames[frame].palette.colors_count; i *= 2, j++);
|
||||
pack_putc ((j ? 128 : 0) + (j ? j - 1 : 0), file);
|
||||
for (i = 1, j = 0; i < gif->frames[frame].palette.colors_count; i *= 2, j++);
|
||||
fputc ((j ? 128 : 0) + (j ? j - 1 : 0), file);
|
||||
|
||||
if (j)
|
||||
write_palette (file, &gif->frames[frame].palette, j);
|
||||
if (j)
|
||||
write_palette (file, &gif->frames[frame].palette, j);
|
||||
|
||||
LZW_encode (file, lzw_read_pixel, w * h,
|
||||
gif->frames[frame].bitmap_8_bit);
|
||||
LZW_encode (file, lzw_read_pixel, w * h,
|
||||
gif->frames[frame].bitmap_8_bit);
|
||||
|
||||
pack_putc (0x00, file); /* Terminator. */
|
||||
fputc (0x00, file); /* Terminator. */
|
||||
|
||||
progress(dp, (float)frame / (float)gif->frames_count);
|
||||
}
|
||||
progress(dp, 1.0f);
|
||||
|
||||
pack_putc (0x3b, file); /* Trailer. */
|
||||
fputc (0x3b, file); /* Trailer. */
|
||||
|
||||
pack_fclose (file);
|
||||
fclose (file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -187,26 +189,26 @@ deinterlace (unsigned char *bmp, int w, int h)
|
||||
int y, i = 0;
|
||||
for (y = 0; y < h; y += 8)
|
||||
{
|
||||
memcpy (temp, bmp + i++ * w, w);
|
||||
memcpy (temp, bmp + i++ * w, w);
|
||||
}
|
||||
for (y = 4; y < h; y += 8)
|
||||
{
|
||||
memcpy (temp, bmp + i++ * w, w);
|
||||
memcpy (temp, bmp + i++ * w, w);
|
||||
}
|
||||
for (y = 2; y < h; y += 4)
|
||||
{
|
||||
memcpy (temp, bmp + i++ * w, w);
|
||||
memcpy (temp, bmp + i++ * w, w);
|
||||
}
|
||||
for (y = 1; y < h; y += 2)
|
||||
{
|
||||
memcpy (temp, bmp + i++ * w, w);
|
||||
memcpy (temp, bmp + i++ * w, w);
|
||||
}
|
||||
memcpy (bmp, temp, w * h);
|
||||
free(temp);
|
||||
}
|
||||
|
||||
static GIF_ANIMATION *
|
||||
load_object (PACKFILE * file, long size, void (*progress) (void *, float), void *dp)
|
||||
load_object (FILE * file, long size, void (*progress) (void *, float), void *dp)
|
||||
{
|
||||
int version;
|
||||
unsigned char *bmp = NULL;
|
||||
@ -218,162 +220,162 @@ load_object (PACKFILE * file, long size, void (*progress) (void *, float), void
|
||||
gif->frames_count = 0;
|
||||
|
||||
/* is it really a GIF? */
|
||||
if (pack_getc (file) != 'G')
|
||||
goto error;
|
||||
if (pack_getc (file) != 'I')
|
||||
goto error;
|
||||
if (pack_getc (file) != 'F')
|
||||
goto error;
|
||||
if (pack_getc (file) != '8')
|
||||
goto error;
|
||||
if (fgetc (file) != 'G')
|
||||
goto error;
|
||||
if (fgetc (file) != 'I')
|
||||
goto error;
|
||||
if (fgetc (file) != 'F')
|
||||
goto error;
|
||||
if (fgetc (file) != '8')
|
||||
goto error;
|
||||
/* '7' or '9', for 87a or 89a. */
|
||||
version = pack_getc (file);
|
||||
version = fgetc (file);
|
||||
if (version != '7' && version != '9')
|
||||
goto error;
|
||||
if (pack_getc (file) != 'a')
|
||||
goto error;
|
||||
goto error;
|
||||
if (fgetc (file) != 'a')
|
||||
goto error;
|
||||
|
||||
gif->width = pack_igetw (file);
|
||||
gif->height = pack_igetw (file);
|
||||
i = pack_getc (file);
|
||||
gif->width = fgetw (file);
|
||||
gif->height = fgetw (file);
|
||||
i = fgetc (file);
|
||||
/* Global color table? */
|
||||
if (i & 128)
|
||||
gif->palette.colors_count = 1 << ((i & 7) + 1);
|
||||
gif->palette.colors_count = 1 << ((i & 7) + 1);
|
||||
else
|
||||
gif->palette.colors_count = 0;
|
||||
gif->palette.colors_count = 0;
|
||||
/* Background color is only valid with a global palette. */
|
||||
gif->background_index = pack_getc (file);
|
||||
gif->background_index = fgetc (file);
|
||||
|
||||
/* Skip aspect ratio. */
|
||||
pack_fseek (file, 1);
|
||||
fseek (file, 1, SEEK_CUR);
|
||||
|
||||
if (gif->palette.colors_count)
|
||||
{
|
||||
read_palette (file, &gif->palette);
|
||||
have_global_palette = 1;
|
||||
read_palette (file, &gif->palette);
|
||||
have_global_palette = 1;
|
||||
}
|
||||
|
||||
progress(dp, 0.0f);
|
||||
do
|
||||
{
|
||||
i = pack_getc (file);
|
||||
i = fgetc (file);
|
||||
progress(dp, (float)i / (float)size);
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0x2c: /* Image Descriptor */
|
||||
{
|
||||
int w, h;
|
||||
int interlaced = 0;
|
||||
switch (i)
|
||||
{
|
||||
case 0x2c: /* Image Descriptor */
|
||||
{
|
||||
int w, h;
|
||||
int interlaced = 0;
|
||||
|
||||
frame.xoff = pack_igetw (file);
|
||||
frame.yoff = pack_igetw (file);
|
||||
w = pack_igetw (file);
|
||||
h = pack_igetw (file);
|
||||
bmp = calloc (w, h);
|
||||
if (!bmp)
|
||||
goto error;
|
||||
frame.w = w;
|
||||
frame.h = h;
|
||||
i = pack_getc (file);
|
||||
frame.xoff = fgetw (file);
|
||||
frame.yoff = fgetw (file);
|
||||
w = fgetw (file);
|
||||
h = fgetw (file);
|
||||
bmp = calloc (w, h);
|
||||
if (!bmp)
|
||||
goto error;
|
||||
frame.w = w;
|
||||
frame.h = h;
|
||||
i = fgetc (file);
|
||||
|
||||
/* Local palette. */
|
||||
if (i & 128)
|
||||
{
|
||||
frame.palette.colors_count = 1 << ((i & 7) + 1);
|
||||
read_palette (file, &frame.palette);
|
||||
}
|
||||
else
|
||||
{
|
||||
frame.palette.colors_count = 0;
|
||||
}
|
||||
/* Local palette. */
|
||||
if (i & 128)
|
||||
{
|
||||
frame.palette.colors_count = 1 << ((i & 7) + 1);
|
||||
read_palette (file, &frame.palette);
|
||||
}
|
||||
else
|
||||
{
|
||||
frame.palette.colors_count = 0;
|
||||
}
|
||||
|
||||
if (i & 64)
|
||||
interlaced = 1;
|
||||
if (i & 64)
|
||||
interlaced = 1;
|
||||
|
||||
if (LZW_decode (file, lzw_write_pixel, bmp))
|
||||
goto error;
|
||||
if (LZW_decode (file, lzw_write_pixel, bmp))
|
||||
goto error;
|
||||
|
||||
if (interlaced)
|
||||
deinterlace (bmp, w, h);
|
||||
if (interlaced)
|
||||
deinterlace (bmp, w, h);
|
||||
|
||||
frame.bitmap_8_bit = bmp;
|
||||
bmp = NULL;
|
||||
frame.bitmap_8_bit = bmp;
|
||||
bmp = NULL;
|
||||
|
||||
gif->frames_count++;
|
||||
gif->frames =
|
||||
realloc (gif->frames,
|
||||
gif->frames_count * sizeof *gif->frames);
|
||||
gif->frames[gif->frames_count - 1] = frame;
|
||||
break;
|
||||
}
|
||||
case 0x21: /* Extension Introducer. */
|
||||
j = pack_getc (file); /* Extension Type. */
|
||||
i = pack_getc (file); /* Size. */
|
||||
if (j == 0xf9) /* Graphic Control Extension. */
|
||||
{
|
||||
/* size must be 4 */
|
||||
if (i != 4)
|
||||
goto error;
|
||||
i = pack_getc (file);
|
||||
frame.disposal_method = (i >> 2) & 7;
|
||||
frame.duration = pack_igetw (file);
|
||||
if (i & 1) /* Transparency? */
|
||||
{
|
||||
frame.transparent_index = pack_getc (file);
|
||||
}
|
||||
else
|
||||
{
|
||||
pack_fseek (file, 1);
|
||||
frame.transparent_index = -1;
|
||||
}
|
||||
i = pack_getc (file); /* Size. */
|
||||
}
|
||||
/* Application Extension. */
|
||||
else if (j == 0xff)
|
||||
{
|
||||
if (i == 11)
|
||||
{
|
||||
char name[12];
|
||||
pack_fread (name, 11, file);
|
||||
i = pack_getc (file); /* Size. */
|
||||
name[11] = '\0';
|
||||
if (!strcmp (name, "NETSCAPE2.0"))
|
||||
{
|
||||
if (i == 3)
|
||||
{
|
||||
j = pack_getc (file);
|
||||
gif->loop = pack_igetw (file);
|
||||
if (j != 1)
|
||||
gif->loop = 0;
|
||||
i = pack_getc (file); /* Size. */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
gif->frames_count++;
|
||||
gif->frames =
|
||||
realloc (gif->frames,
|
||||
gif->frames_count * sizeof *gif->frames);
|
||||
gif->frames[gif->frames_count - 1] = frame;
|
||||
break;
|
||||
}
|
||||
case 0x21: /* Extension Introducer. */
|
||||
j = fgetc (file); /* Extension Type. */
|
||||
i = fgetc (file); /* Size. */
|
||||
if (j == 0xf9) /* Graphic Control Extension. */
|
||||
{
|
||||
/* size must be 4 */
|
||||
if (i != 4)
|
||||
goto error;
|
||||
i = fgetc (file);
|
||||
frame.disposal_method = (i >> 2) & 7;
|
||||
frame.duration = fgetw (file);
|
||||
if (i & 1) /* Transparency? */
|
||||
{
|
||||
frame.transparent_index = fgetc (file);
|
||||
}
|
||||
else
|
||||
{
|
||||
fseek (file, 1, SEEK_CUR);
|
||||
frame.transparent_index = -1;
|
||||
}
|
||||
i = fgetc (file); /* Size. */
|
||||
}
|
||||
/* Application Extension. */
|
||||
else if (j == 0xff)
|
||||
{
|
||||
if (i == 11)
|
||||
{
|
||||
char name[12];
|
||||
fread (name, 1, 11, file);
|
||||
i = fgetc (file); /* Size. */
|
||||
name[11] = '\0';
|
||||
if (!strcmp (name, "NETSCAPE2.0"))
|
||||
{
|
||||
if (i == 3)
|
||||
{
|
||||
j = fgetc (file);
|
||||
gif->loop = fgetw (file);
|
||||
if (j != 1)
|
||||
gif->loop = 0;
|
||||
i = fgetc (file); /* Size. */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Possibly more blocks until terminator block (0). */
|
||||
while (i)
|
||||
{
|
||||
pack_fseek (file, i);
|
||||
i = pack_getc (file);
|
||||
}
|
||||
break;
|
||||
case 0x3b:
|
||||
/* GIF Trailer. */
|
||||
pack_fclose (file);
|
||||
/* Possibly more blocks until terminator block (0). */
|
||||
while (i)
|
||||
{
|
||||
fseek (file, i, SEEK_CUR);
|
||||
i = fgetc (file);
|
||||
}
|
||||
break;
|
||||
case 0x3b:
|
||||
/* GIF Trailer. */
|
||||
fclose (file);
|
||||
progress(dp, 1.0f);
|
||||
return gif;
|
||||
}
|
||||
return gif;
|
||||
}
|
||||
}
|
||||
while (TRUE);
|
||||
error:
|
||||
if (file)
|
||||
pack_fclose (file);
|
||||
fclose (file);
|
||||
if (gif)
|
||||
gif_destroy_animation (gif);
|
||||
gif_destroy_animation (gif);
|
||||
if (bmp)
|
||||
free (bmp);
|
||||
free (bmp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -391,7 +393,7 @@ load_object (PACKFILE * file, long size, void (*progress) (void *, float), void
|
||||
GIF_ANIMATION *
|
||||
gif_load_animation (const char *filename, void (*progress) (void *, float), void *dp)
|
||||
{
|
||||
PACKFILE *file;
|
||||
FILE *file;
|
||||
GIF_ANIMATION *gif = NULL;
|
||||
#if (MAKE_VERSION(4, 2, 1) >= MAKE_VERSION(ALLEGRO_VERSION, \
|
||||
ALLEGRO_SUB_VERSION, \
|
||||
@ -401,7 +403,7 @@ gif_load_animation (const char *filename, void (*progress) (void *, float), void
|
||||
int size = file_size_ex(filename);
|
||||
#endif
|
||||
|
||||
file = pack_fopen (filename, "r");
|
||||
file = fopen (filename, "rb");
|
||||
if (file)
|
||||
gif = load_object (file, size, progress, dp);
|
||||
return gif;
|
||||
@ -412,4 +414,3 @@ gif_load_animation (const char *filename, void (*progress) (void *, float), void
|
||||
/* { */
|
||||
/* return makecol (rgb->r, rgb->g, rgb->b); */
|
||||
/* } */
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "lzw.h"
|
||||
#include "file/gif/lzw.h"
|
||||
|
||||
static int
|
||||
read_code (PACKFILE * file, unsigned char *buf, int *bit_pos, int bit_size)
|
||||
read_code (FILE * file, unsigned char *buf, int *bit_pos, int bit_size)
|
||||
{
|
||||
int i;
|
||||
int code = 0;
|
||||
@ -13,7 +13,7 @@ read_code (PACKFILE * file, unsigned char *buf, int *bit_pos, int bit_size)
|
||||
|
||||
if (byte_pos == 0)
|
||||
{
|
||||
int data_len = pack_getc (file);
|
||||
int data_len = fgetc (file);
|
||||
|
||||
if (data_len == 0)
|
||||
{
|
||||
@ -21,7 +21,7 @@ read_code (PACKFILE * file, unsigned char *buf, int *bit_pos, int bit_size)
|
||||
//abort ();
|
||||
return -1;
|
||||
}
|
||||
pack_fread (buf + 256 - data_len, data_len, file);
|
||||
fread (buf + 256 - data_len, 1, data_len, file);
|
||||
byte_pos = 256 - data_len;
|
||||
*bit_pos = byte_pos << 3;
|
||||
}
|
||||
@ -34,7 +34,7 @@ read_code (PACKFILE * file, unsigned char *buf, int *bit_pos, int bit_size)
|
||||
}
|
||||
|
||||
static void
|
||||
write_code (PACKFILE * file, unsigned char *buf, int *bit_pos, int bit_size, int code)
|
||||
write_code (FILE * file, unsigned char *buf, int *bit_pos, int bit_size, int code)
|
||||
{
|
||||
int i;
|
||||
int pos = 1;
|
||||
@ -50,8 +50,8 @@ write_code (PACKFILE * file, unsigned char *buf, int *bit_pos, int bit_size, int
|
||||
(*bit_pos)++;
|
||||
if (*bit_pos == 2040)
|
||||
{
|
||||
pack_putc (byte_pos + 1, file);
|
||||
pack_fwrite (buf, byte_pos + 1, file);
|
||||
fputc (byte_pos + 1, file);
|
||||
fwrite (buf, 1, byte_pos + 1, file);
|
||||
*bit_pos = 0;
|
||||
}
|
||||
pos += pos;
|
||||
@ -59,7 +59,7 @@ write_code (PACKFILE * file, unsigned char *buf, int *bit_pos, int bit_size, int
|
||||
}
|
||||
|
||||
int
|
||||
LZW_decode (PACKFILE * file,
|
||||
LZW_decode (FILE * file,
|
||||
void (*write_pixel)(int pos, int code, unsigned char *data),
|
||||
unsigned char *data)
|
||||
{
|
||||
@ -80,7 +80,7 @@ LZW_decode (PACKFILE * file,
|
||||
int i, prev, code, c;
|
||||
int out_pos = 0;
|
||||
|
||||
orig_bit_size = pack_getc (file);
|
||||
orig_bit_size = fgetc (file);
|
||||
n = 2 + (1 << orig_bit_size);
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
@ -188,7 +188,7 @@ get_minimum_bitsize (int (*read_pixel)(int pos, unsigned char *data),
|
||||
}
|
||||
|
||||
void
|
||||
LZW_encode (PACKFILE * file, int (*read_pixel)(int pos, unsigned char *data),
|
||||
LZW_encode (FILE * file, int (*read_pixel)(int pos, unsigned char *data),
|
||||
int size, unsigned char *data)
|
||||
{
|
||||
unsigned char buf[256];
|
||||
@ -221,7 +221,7 @@ LZW_encode (PACKFILE * file, int (*read_pixel)(int pos, unsigned char *data),
|
||||
clear_marker = n - 2;
|
||||
end_marker = n - 1;
|
||||
|
||||
pack_putc (orig_bit_size, file);
|
||||
fputc (orig_bit_size, file);
|
||||
|
||||
bit_size = orig_bit_size + 1;
|
||||
|
||||
@ -283,7 +283,7 @@ LZW_encode (PACKFILE * file, int (*read_pixel)(int pos, unsigned char *data),
|
||||
{
|
||||
int byte_pos = (bit_pos + 7) / 8;
|
||||
|
||||
pack_putc (byte_pos, file);
|
||||
pack_fwrite (buf, byte_pos, file);
|
||||
fputc (byte_pos, file);
|
||||
fwrite (buf, 1, byte_pos, file);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
#ifndef _LZW_H_
|
||||
#define _LZW_H_
|
||||
#include <allegro/file.h>
|
||||
int LZW_decode (PACKFILE *file, void (*write_pixel)(int pos, int code, unsigned char *data), unsigned char *data);
|
||||
void LZW_encode (PACKFILE *file, int (*read_pixel)(int pos, unsigned char *data), int size, unsigned char *data);
|
||||
#include <stdio.h>
|
||||
int LZW_decode (FILE *file, void (*write_pixel)(int pos, int code, unsigned char *data), unsigned char *data);
|
||||
void LZW_encode (FILE *file, int (*read_pixel)(int pos, unsigned char *data), int size, unsigned char *data);
|
||||
#endif
|
||||
|
@ -23,7 +23,6 @@
|
||||
#ifndef USE_PRECOMPILED_HEADER
|
||||
|
||||
#include <allegro/color.h>
|
||||
#include <allegro/file.h>
|
||||
|
||||
#include "file/file.h"
|
||||
#include "raster/raster.h"
|
||||
@ -51,23 +50,23 @@ FileFormat format_ico =
|
||||
|
||||
static bool save_ICO(FileOp *fop)
|
||||
{
|
||||
PACKFILE *f;
|
||||
FILE *f;
|
||||
int depth, bpp, bw, bitsw;
|
||||
int size, offset, n, i;
|
||||
int c, x, y, b, m, v;
|
||||
int num = fop->sprite->frames;
|
||||
Image *bmp;
|
||||
|
||||
f = pack_fopen(fop->filename, F_WRITE);
|
||||
f = fopen(fop->filename, "wb");
|
||||
if (!f)
|
||||
return FALSE;
|
||||
|
||||
offset = 6 + num * 16; /* ICONDIR + ICONDIRENTRYs */
|
||||
|
||||
/* ICONDIR */
|
||||
pack_iputw(0, f); /* reserved */
|
||||
pack_iputw(1, f); /* resource type: ICON */
|
||||
pack_iputw(num, f); /* number of icons */
|
||||
fputw(0, f); /* reserved */
|
||||
fputw(1, f); /* resource type: ICON */
|
||||
fputw(num, f); /* number of icons */
|
||||
|
||||
for(n = 0; n < num; n++) {
|
||||
depth = 8;/* bitmap_color_depth(bmp[n]); */
|
||||
@ -80,14 +79,14 @@ static bool save_ICO(FileOp *fop)
|
||||
size += 256 * 4;
|
||||
|
||||
/* ICONDIRENTRY */
|
||||
pack_putc(fop->sprite->w, f); /* width */
|
||||
pack_putc(fop->sprite->h, f); /* height */
|
||||
pack_putc(0, f); /* color count */
|
||||
pack_putc(0, f); /* reserved */
|
||||
pack_iputw(1, f); /* color planes */
|
||||
pack_iputw(bpp, f); /* bits per pixel */
|
||||
pack_iputl(size, f); /* size in bytes of image data */
|
||||
pack_iputl(offset, f); /* file offset to image data */
|
||||
fputc(fop->sprite->w, f); /* width */
|
||||
fputc(fop->sprite->h, f); /* height */
|
||||
fputc(0, f); /* color count */
|
||||
fputc(0, f); /* reserved */
|
||||
fputw(1, f); /* color planes */
|
||||
fputw(bpp, f); /* bits per pixel */
|
||||
fputl(size, f); /* size in bytes of image data */
|
||||
fputl(offset, f); /* file offset to image data */
|
||||
|
||||
offset += size;
|
||||
}
|
||||
@ -110,29 +109,29 @@ static bool save_ICO(FileOp *fop)
|
||||
size += 256 * 4;
|
||||
|
||||
/* BITMAPINFOHEADER */
|
||||
pack_iputl(40, f); /* size */
|
||||
pack_iputl(bmp->w, f); /* width */
|
||||
pack_iputl(bmp->h * 2, f); /* height x 2 */
|
||||
pack_iputw(1, f); /* planes */
|
||||
pack_iputw(bpp, f); /* bitcount */
|
||||
pack_iputl(0, f); /* unused for ico */
|
||||
pack_iputl(size, f); /* size */
|
||||
pack_iputl(0, f); /* unused for ico */
|
||||
pack_iputl(0, f); /* unused for ico */
|
||||
pack_iputl(0, f); /* unused for ico */
|
||||
pack_iputl(0, f); /* unused for ico */
|
||||
fputl(40, f); /* size */
|
||||
fputl(bmp->w, f); /* width */
|
||||
fputl(bmp->h * 2, f); /* height x 2 */
|
||||
fputw(1, f); /* planes */
|
||||
fputw(bpp, f); /* bitcount */
|
||||
fputl(0, f); /* unused for ico */
|
||||
fputl(size, f); /* size */
|
||||
fputl(0, f); /* unused for ico */
|
||||
fputl(0, f); /* unused for ico */
|
||||
fputl(0, f); /* unused for ico */
|
||||
fputl(0, f); /* unused for ico */
|
||||
|
||||
/* PALETTE */
|
||||
if (bpp == 8) {
|
||||
RGB *pal = sprite_get_palette(fop->sprite, n);
|
||||
|
||||
pack_iputl(0, f); /* color 0 is black, so the XOR mask works */
|
||||
fputl(0, f); /* color 0 is black, so the XOR mask works */
|
||||
|
||||
for (i = 1; i<256; i++) {
|
||||
pack_putc(_rgb_scale_6[pal[i].b], f);
|
||||
pack_putc(_rgb_scale_6[pal[i].g], f);
|
||||
pack_putc(_rgb_scale_6[pal[i].r], f);
|
||||
pack_putc(0, f);
|
||||
fputc(_rgb_scale_6[pal[i].b], f);
|
||||
fputc(_rgb_scale_6[pal[i].g], f);
|
||||
fputc(_rgb_scale_6[pal[i].r], f);
|
||||
fputc(0, f);
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,19 +139,19 @@ static bool save_ICO(FileOp *fop)
|
||||
for (y = bmp->h - 1; y >= 0; y--) {
|
||||
for (x = 0; x < bmp->w; x++) {
|
||||
if (bpp == 8) {
|
||||
pack_putc(image_getpixel(bmp, x, y), f);
|
||||
fputc(image_getpixel(bmp, x, y), f);
|
||||
}
|
||||
else {
|
||||
c = image_getpixel(bmp, x, y);
|
||||
pack_putc(getb_depth(depth, c), f);
|
||||
pack_putc(getg_depth(depth, c), f);
|
||||
pack_putc(getr_depth(depth, c), f);
|
||||
fputc(getb_depth(depth, c), f);
|
||||
fputc(getg_depth(depth, c), f);
|
||||
fputc(getr_depth(depth, c), f);
|
||||
}
|
||||
}
|
||||
|
||||
/* every scanline must be 32-bit aligned */
|
||||
while (x&3) {
|
||||
pack_putc(0, f);
|
||||
fputc(0, f);
|
||||
x++;
|
||||
}
|
||||
}
|
||||
@ -170,19 +169,19 @@ static bool save_ICO(FileOp *fop)
|
||||
v /= 2;
|
||||
}
|
||||
|
||||
pack_putc(m, f);
|
||||
fputc(m, f);
|
||||
}
|
||||
|
||||
/* every scanline must be 32-bit aligned */
|
||||
while (x&3) {
|
||||
pack_putc(0, f);
|
||||
fputc(0, f);
|
||||
x++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
image_free(bmp);
|
||||
pack_fclose(f);
|
||||
fclose(f);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -208,6 +208,8 @@ static bool load_JPEG(FileOp *fop)
|
||||
}
|
||||
|
||||
fop_progress(fop, (float)(cinfo.output_scanline+1) / (float)(cinfo.output_height));
|
||||
if (fop_is_stop(fop))
|
||||
break;
|
||||
}
|
||||
|
||||
/* destroy all data */
|
||||
|
@ -23,7 +23,6 @@
|
||||
#ifndef USE_PRECOMPILED_HEADER
|
||||
|
||||
#include <allegro/color.h>
|
||||
#include <allegro/file.h>
|
||||
|
||||
#include "file/file.h"
|
||||
#include "raster/raster.h"
|
||||
@ -48,7 +47,7 @@ FileFormat format_pcx =
|
||||
static bool load_PCX(FileOp *fop)
|
||||
{
|
||||
Image *image;
|
||||
PACKFILE *f;
|
||||
FILE *f;
|
||||
int c, r, g, b;
|
||||
int width, height;
|
||||
int bpp, bytes_per_line;
|
||||
@ -56,70 +55,68 @@ static bool load_PCX(FileOp *fop)
|
||||
int x, y;
|
||||
char ch = 0;
|
||||
|
||||
f = pack_fopen(fop->filename, F_READ);
|
||||
f = fopen(fop->filename, "rb");
|
||||
if (!f)
|
||||
return FALSE;
|
||||
|
||||
pack_getc(f); /* skip manufacturer ID */
|
||||
pack_getc(f); /* skip version flag */
|
||||
pack_getc(f); /* skip encoding flag */
|
||||
fgetc(f); /* skip manufacturer ID */
|
||||
fgetc(f); /* skip version flag */
|
||||
fgetc(f); /* skip encoding flag */
|
||||
|
||||
if (pack_getc(f) != 8) { /* we like 8 bit color planes */
|
||||
if (fgetc(f) != 8) { /* we like 8 bit color planes */
|
||||
fop_error(fop, _("This PCX doesn't have 8 bit color planes.\n"));
|
||||
pack_fclose(f);
|
||||
fclose(f);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
width = -(pack_igetw(f)); /* xmin */
|
||||
height = -(pack_igetw(f)); /* ymin */
|
||||
width += pack_igetw(f) + 1; /* xmax */
|
||||
height += pack_igetw(f) + 1; /* ymax */
|
||||
width = -(fgetw(f)); /* xmin */
|
||||
height = -(fgetw(f)); /* ymin */
|
||||
width += fgetw(f) + 1; /* xmax */
|
||||
height += fgetw(f) + 1; /* ymax */
|
||||
|
||||
pack_igetl(f); /* skip DPI values */
|
||||
fgetl(f); /* skip DPI values */
|
||||
|
||||
for (c=0; c<16; c++) { /* read the 16 color palette */
|
||||
r = pack_getc(f) / 4;
|
||||
g = pack_getc(f) / 4;
|
||||
b = pack_getc(f) / 4;
|
||||
for (c=0; c<16; c++) { /* read the 16 color palette */
|
||||
r = fgetc(f) / 4;
|
||||
g = fgetc(f) / 4;
|
||||
b = fgetc(f) / 4;
|
||||
fop_sequence_set_color(fop, c, r, g, b);
|
||||
}
|
||||
|
||||
pack_getc(f);
|
||||
fgetc(f);
|
||||
|
||||
bpp = pack_getc(f) * 8; /* how many color planes? */
|
||||
bpp = fgetc(f) * 8; /* how many color planes? */
|
||||
if ((bpp != 8) && (bpp != 24)) {
|
||||
pack_fclose(f);
|
||||
fclose(f);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bytes_per_line = pack_igetw(f);
|
||||
bytes_per_line = fgetw(f);
|
||||
|
||||
for (c=0; c<60; c++) /* skip some more junk */
|
||||
pack_getc(f);
|
||||
fgetc(f);
|
||||
|
||||
image = fop_sequence_image(fop, bpp == 8 ?
|
||||
IMAGE_INDEXED:
|
||||
IMAGE_RGB,
|
||||
width, height);
|
||||
if (!image) {
|
||||
pack_fclose(f);
|
||||
fclose(f);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (bpp == 24)
|
||||
image_clear(image, _rgba(0, 0, 0, 255));
|
||||
|
||||
*allegro_errno = 0;
|
||||
|
||||
for (y=0; y<height; y++) { /* read RLE encoded PCX data */
|
||||
x = xx = 0;
|
||||
po = _rgba_r_shift;
|
||||
|
||||
while (x < bytes_per_line*bpp/8) {
|
||||
ch = pack_getc(f);
|
||||
ch = fgetc(f);
|
||||
if ((ch & 0xC0) == 0xC0) {
|
||||
c = (ch & 0x3F);
|
||||
ch = pack_getc(f);
|
||||
ch = fgetc(f);
|
||||
}
|
||||
else
|
||||
c = 1;
|
||||
@ -151,36 +148,41 @@ static bool load_PCX(FileOp *fop)
|
||||
}
|
||||
|
||||
fop_progress(fop, (float)(y+1) / (float)(height));
|
||||
if (fop_is_stop(fop))
|
||||
break;
|
||||
}
|
||||
|
||||
if (bpp == 8) { /* look for a 256 color palette */
|
||||
while ((c = pack_getc(f)) != EOF) {
|
||||
if (c == 12) {
|
||||
for (c=0; c<256; c++) {
|
||||
r = pack_getc(f) / 4;
|
||||
g = pack_getc(f) / 4;
|
||||
b = pack_getc(f) / 4;
|
||||
fop_sequence_set_color(fop, c, r, g, b);
|
||||
}
|
||||
break;
|
||||
if (!fop_is_stop(fop)) {
|
||||
if (bpp == 8) { /* look for a 256 color palette */
|
||||
while ((c = fgetc(f)) != EOF) {
|
||||
if (c == 12) {
|
||||
for (c=0; c<256; c++) {
|
||||
r = fgetc(f) / 4;
|
||||
g = fgetc(f) / 4;
|
||||
b = fgetc(f) / 4;
|
||||
fop_sequence_set_color(fop, c, r, g, b);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (*allegro_errno) {
|
||||
fop_error(fop, _("Error reading bytes.\n"));
|
||||
pack_fclose(f);
|
||||
if (ferror(f)) {
|
||||
fop_error(fop, _("Error reading file.\n"));
|
||||
fclose(f);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pack_fclose(f);
|
||||
return TRUE;
|
||||
else {
|
||||
fclose(f);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static bool save_PCX(FileOp *fop)
|
||||
{
|
||||
Image *image = fop->seq.image;
|
||||
PACKFILE *f;
|
||||
FILE *f;
|
||||
int c, r, g, b;
|
||||
int x, y;
|
||||
int runcount;
|
||||
@ -188,7 +190,7 @@ static bool save_PCX(FileOp *fop)
|
||||
char runchar;
|
||||
char ch = 0;
|
||||
|
||||
f = pack_fopen(fop->filename, F_WRITE);
|
||||
f = fopen(fop->filename, "wb");
|
||||
if (!f) {
|
||||
fop_error(fop, _("Error creating file.\n"));
|
||||
return FALSE;
|
||||
@ -203,34 +205,32 @@ static bool save_PCX(FileOp *fop)
|
||||
planes = 1;
|
||||
}
|
||||
|
||||
*allegro_errno = 0;
|
||||
|
||||
pack_putc(10, f); /* manufacturer */
|
||||
pack_putc(5, f); /* version */
|
||||
pack_putc(1, f); /* run length encoding */
|
||||
pack_putc(8, f); /* 8 bits per pixel */
|
||||
pack_iputw(0, f); /* xmin */
|
||||
pack_iputw(0, f); /* ymin */
|
||||
pack_iputw(image->w-1, f); /* xmax */
|
||||
pack_iputw(image->h-1, f); /* ymax */
|
||||
pack_iputw(320, f); /* HDpi */
|
||||
pack_iputw(200, f); /* VDpi */
|
||||
fputc(10, f); /* manufacturer */
|
||||
fputc(5, f); /* version */
|
||||
fputc(1, f); /* run length encoding */
|
||||
fputc(8, f); /* 8 bits per pixel */
|
||||
fputw(0, f); /* xmin */
|
||||
fputw(0, f); /* ymin */
|
||||
fputw(image->w-1, f); /* xmax */
|
||||
fputw(image->h-1, f); /* ymax */
|
||||
fputw(320, f); /* HDpi */
|
||||
fputw(200, f); /* VDpi */
|
||||
|
||||
for (c=0; c<16; c++) {
|
||||
fop_sequence_get_color(fop, c, &r, &g, &b);
|
||||
pack_putc(_rgb_scale_6[r], f);
|
||||
pack_putc(_rgb_scale_6[g], f);
|
||||
pack_putc(_rgb_scale_6[b], f);
|
||||
fputc(_rgb_scale_6[r], f);
|
||||
fputc(_rgb_scale_6[g], f);
|
||||
fputc(_rgb_scale_6[b], f);
|
||||
}
|
||||
|
||||
pack_putc(0, f); /* reserved */
|
||||
pack_putc(planes, f); /* one or three color planes */
|
||||
pack_iputw(image->w, f); /* number of bytes per scanline */
|
||||
pack_iputw(1, f); /* color palette */
|
||||
pack_iputw(image->w, f); /* hscreen size */
|
||||
pack_iputw(image->h, f); /* vscreen size */
|
||||
for (c=0; c<54; c++) /* filler */
|
||||
pack_putc(0, f);
|
||||
fputc(0, f); /* reserved */
|
||||
fputc(planes, f); /* one or three color planes */
|
||||
fputw(image->w, f); /* number of bytes per scanline */
|
||||
fputw(1, f); /* color palette */
|
||||
fputw(image->w, f); /* hscreen size */
|
||||
fputw(image->h, f); /* vscreen size */
|
||||
for (c=0; c<54; c++) /* filler */
|
||||
fputc(0, f);
|
||||
|
||||
for (y=0; y<image->h; y++) { /* for each scanline... */
|
||||
runcount = 0;
|
||||
@ -265,8 +265,8 @@ static bool save_PCX(FileOp *fop)
|
||||
else {
|
||||
if ((ch != runchar) || (runcount >= 0x3f)) {
|
||||
if ((runcount > 1) || ((runchar & 0xC0) == 0xC0))
|
||||
pack_putc(0xC0 | runcount, f);
|
||||
pack_putc(runchar, f);
|
||||
fputc(0xC0 | runcount, f);
|
||||
fputc(runchar, f);
|
||||
runcount = 1;
|
||||
runchar = ch;
|
||||
}
|
||||
@ -276,30 +276,31 @@ static bool save_PCX(FileOp *fop)
|
||||
}
|
||||
|
||||
if ((runcount > 1) || ((runchar & 0xC0) == 0xC0))
|
||||
pack_putc(0xC0 | runcount, f);
|
||||
fputc(0xC0 | runcount, f);
|
||||
|
||||
pack_putc(runchar, f);
|
||||
fputc(runchar, f);
|
||||
|
||||
fop_progress(fop, (float)(y+1) / (float)(image->h));
|
||||
}
|
||||
|
||||
if (depth == 8) { /* 256 color palette */
|
||||
pack_putc(12, f);
|
||||
fputc(12, f);
|
||||
|
||||
for (c=0; c<256; c++) {
|
||||
fop_sequence_get_color(fop, c, &r, &g, &b);
|
||||
pack_putc(_rgb_scale_6[r], f);
|
||||
pack_putc(_rgb_scale_6[g], f);
|
||||
pack_putc(_rgb_scale_6[b], f);
|
||||
fputc(_rgb_scale_6[r], f);
|
||||
fputc(_rgb_scale_6[g], f);
|
||||
fputc(_rgb_scale_6[b], f);
|
||||
}
|
||||
}
|
||||
|
||||
pack_fclose(f);
|
||||
|
||||
if (*allegro_errno) {
|
||||
fop_error(fop, _("Error writing bytes.\n"));
|
||||
if (ferror(f)) {
|
||||
fop_error(fop, _("Error writing file.\n"));
|
||||
fclose(f);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
else {
|
||||
fclose(f);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -276,6 +276,9 @@ static bool load_PNG(FileOp *fop)
|
||||
fop_progress(fop,
|
||||
(float)((float)pass + (float)(y+1) / (float)(height))
|
||||
/ (float)number_passes);
|
||||
|
||||
if (fop_is_stop(fop))
|
||||
break;
|
||||
}
|
||||
}
|
||||
png_free(png_ptr, row_pointer);
|
||||
|
@ -24,7 +24,6 @@
|
||||
#ifndef USE_PRECOMPILED_HEADER
|
||||
|
||||
#include <allegro/color.h>
|
||||
#include <allegro/file.h>
|
||||
|
||||
#include "jinete/jbase.h"
|
||||
|
||||
@ -52,18 +51,18 @@ FileFormat format_tga =
|
||||
/* rle_tga_read:
|
||||
* Helper for reading 256 color RLE data from TGA files.
|
||||
*/
|
||||
static void rle_tga_read(unsigned char *address, int w, int type, PACKFILE *f)
|
||||
static void rle_tga_read(unsigned char *address, int w, int type, FILE *f)
|
||||
{
|
||||
unsigned char value;
|
||||
int count, g;
|
||||
int c = 0;
|
||||
|
||||
do {
|
||||
count = pack_getc(f);
|
||||
count = fgetc(f);
|
||||
if (count & 0x80) {
|
||||
count = (count & 0x7F) + 1;
|
||||
c += count;
|
||||
value = pack_getc(f);
|
||||
value = fgetc(f);
|
||||
while (count--) {
|
||||
if (type == 1)
|
||||
*(address++) = value;
|
||||
@ -77,12 +76,12 @@ static void rle_tga_read(unsigned char *address, int w, int type, PACKFILE *f)
|
||||
count++;
|
||||
c += count;
|
||||
if (type == 1) {
|
||||
pack_fread(address, count, f);
|
||||
fread(address, 1, count, f);
|
||||
address += count;
|
||||
}
|
||||
else {
|
||||
for (g=0; g<count; g++) {
|
||||
*((ase_uint16 *)address) = pack_getc(f);
|
||||
*((ase_uint16 *)address) = fgetc(f);
|
||||
address += sizeof(ase_uint16);
|
||||
}
|
||||
}
|
||||
@ -93,18 +92,18 @@ static void rle_tga_read(unsigned char *address, int w, int type, PACKFILE *f)
|
||||
/* rle_tga_read32:
|
||||
* Helper for reading 32 bit RLE data from TGA files.
|
||||
*/
|
||||
static void rle_tga_read32 (ase_uint32 *address, int w, PACKFILE *f)
|
||||
static void rle_tga_read32 (ase_uint32 *address, int w, FILE *f)
|
||||
{
|
||||
unsigned char value[4];
|
||||
int count;
|
||||
int c = 0;
|
||||
|
||||
do {
|
||||
count = pack_getc(f);
|
||||
count = fgetc(f);
|
||||
if (count & 0x80) {
|
||||
count = (count & 0x7F) + 1;
|
||||
c += count;
|
||||
pack_fread(value, 4, f);
|
||||
fread(value, 1, 4, f);
|
||||
while (count--)
|
||||
*(address++) = _rgba(value[2], value[1], value[0], value[3]);
|
||||
}
|
||||
@ -112,7 +111,7 @@ static void rle_tga_read32 (ase_uint32 *address, int w, PACKFILE *f)
|
||||
count++;
|
||||
c += count;
|
||||
while (count--) {
|
||||
pack_fread(value, 4, f);
|
||||
fread(value, 1, 4, f);
|
||||
*(address++) = _rgba(value[2], value[1], value[0], value[3]);
|
||||
}
|
||||
}
|
||||
@ -122,18 +121,18 @@ static void rle_tga_read32 (ase_uint32 *address, int w, PACKFILE *f)
|
||||
/* rle_tga_read24:
|
||||
* Helper for reading 24 bit RLE data from TGA files.
|
||||
*/
|
||||
static void rle_tga_read24(ase_uint32 *address, int w, PACKFILE *f)
|
||||
static void rle_tga_read24(ase_uint32 *address, int w, FILE *f)
|
||||
{
|
||||
unsigned char value[4];
|
||||
int count;
|
||||
int c = 0;
|
||||
|
||||
do {
|
||||
count = pack_getc(f);
|
||||
count = fgetc(f);
|
||||
if (count & 0x80) {
|
||||
count = (count & 0x7F) + 1;
|
||||
c += count;
|
||||
pack_fread(value, 3, f);
|
||||
fread(value, 1, 3, f);
|
||||
while (count--)
|
||||
*(address++) = _rgba(value[2], value[1], value[0], 255);
|
||||
}
|
||||
@ -141,7 +140,7 @@ static void rle_tga_read24(ase_uint32 *address, int w, PACKFILE *f)
|
||||
count++;
|
||||
c += count;
|
||||
while (count--) {
|
||||
pack_fread(value, 3, f);
|
||||
fread(value, 1, 3, f);
|
||||
*(address++) = _rgba(value[2], value[1], value[0], 255);
|
||||
}
|
||||
}
|
||||
@ -151,7 +150,7 @@ static void rle_tga_read24(ase_uint32 *address, int w, PACKFILE *f)
|
||||
/* rle_tga_read16:
|
||||
* Helper for reading 16 bit RLE data from TGA files.
|
||||
*/
|
||||
static void rle_tga_read16(ase_uint32 *address, int w, PACKFILE *f)
|
||||
static void rle_tga_read16(ase_uint32 *address, int w, FILE *f)
|
||||
{
|
||||
unsigned int value;
|
||||
ase_uint32 color;
|
||||
@ -159,11 +158,11 @@ static void rle_tga_read16(ase_uint32 *address, int w, PACKFILE *f)
|
||||
int c = 0;
|
||||
|
||||
do {
|
||||
count = pack_getc(f);
|
||||
count = fgetc(f);
|
||||
if (count & 0x80) {
|
||||
count = (count & 0x7F) + 1;
|
||||
c += count;
|
||||
value = pack_igetw(f);
|
||||
value = fgetw(f);
|
||||
color = _rgba(_rgb_scale_5[((value >> 10) & 0x1F)],
|
||||
_rgb_scale_5[((value >> 5) & 0x1F)],
|
||||
_rgb_scale_5[(value & 0x1F)], 255);
|
||||
@ -175,7 +174,7 @@ static void rle_tga_read16(ase_uint32 *address, int w, PACKFILE *f)
|
||||
count++;
|
||||
c += count;
|
||||
while (count--) {
|
||||
value = pack_igetw(f);
|
||||
value = fgetw(f);
|
||||
color = _rgba(_rgb_scale_5[((value >> 10) & 0x1F)],
|
||||
_rgb_scale_5[((value >> 5) & 0x1F)],
|
||||
_rgb_scale_5[(value & 0x1F)], 255);
|
||||
@ -200,36 +199,34 @@ static bool load_TGA(FileOp *fop)
|
||||
unsigned int c, i, x, y, yc;
|
||||
Image *image;
|
||||
int compressed;
|
||||
PACKFILE *f;
|
||||
FILE *f;
|
||||
int type;
|
||||
|
||||
f = pack_fopen(fop->filename, F_READ);
|
||||
f = fopen(fop->filename, "rb");
|
||||
if (!f)
|
||||
return FALSE;
|
||||
|
||||
*allegro_errno = 0;
|
||||
id_length = fgetc(f);
|
||||
palette_type = fgetc(f);
|
||||
image_type = fgetc(f);
|
||||
first_color = fgetw(f);
|
||||
palette_colors = fgetw(f);
|
||||
palette_entry_size = fgetc(f);
|
||||
left = fgetw(f);
|
||||
top = fgetw(f);
|
||||
image_width = fgetw(f);
|
||||
image_height = fgetw(f);
|
||||
bpp = fgetc(f);
|
||||
descriptor_bits = fgetc(f);
|
||||
|
||||
id_length = pack_getc(f);
|
||||
palette_type = pack_getc(f);
|
||||
image_type = pack_getc(f);
|
||||
first_color = pack_igetw(f);
|
||||
palette_colors = pack_igetw(f);
|
||||
palette_entry_size = pack_getc(f);
|
||||
left = pack_igetw(f);
|
||||
top = pack_igetw(f);
|
||||
image_width = pack_igetw(f);
|
||||
image_height = pack_igetw(f);
|
||||
bpp = pack_getc(f);
|
||||
descriptor_bits = pack_getc(f);
|
||||
|
||||
pack_fread(image_id, id_length, f);
|
||||
fread(image_id, 1, id_length, f);
|
||||
|
||||
if (palette_type == 1) {
|
||||
for (i=0; i<palette_colors; i++) {
|
||||
switch (palette_entry_size) {
|
||||
|
||||
case 16:
|
||||
c = pack_igetw(f);
|
||||
c = fgetw(f);
|
||||
image_palette[i][0] = (c & 0x1F) << 3;
|
||||
image_palette[i][1] = ((c >> 5) & 0x1F) << 3;
|
||||
image_palette[i][2] = ((c >> 10) & 0x1F) << 3;
|
||||
@ -237,17 +234,17 @@ static bool load_TGA(FileOp *fop)
|
||||
|
||||
case 24:
|
||||
case 32:
|
||||
image_palette[i][0] = pack_getc(f);
|
||||
image_palette[i][1] = pack_getc(f);
|
||||
image_palette[i][2] = pack_getc(f);
|
||||
image_palette[i][0] = fgetc(f);
|
||||
image_palette[i][1] = fgetc(f);
|
||||
image_palette[i][2] = fgetc(f);
|
||||
if (palette_entry_size == 32)
|
||||
pack_getc(f);
|
||||
fgetc(f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (palette_type != 0) {
|
||||
pack_fclose(f);
|
||||
fclose(f);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -268,7 +265,7 @@ static bool load_TGA(FileOp *fop)
|
||||
/* paletted image */
|
||||
case 1:
|
||||
if ((palette_type != 1) || (bpp != 8)) {
|
||||
pack_fclose(f);
|
||||
fclose(f);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -287,7 +284,7 @@ static bool load_TGA(FileOp *fop)
|
||||
if ((palette_type != 0) ||
|
||||
((bpp != 15) && (bpp != 16) &&
|
||||
(bpp != 24) && (bpp != 32))) {
|
||||
pack_fclose(f);
|
||||
fclose(f);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -297,7 +294,7 @@ static bool load_TGA(FileOp *fop)
|
||||
/* grayscale image */
|
||||
case 3:
|
||||
if ((palette_type != 0) || (bpp != 8)) {
|
||||
pack_fclose(f);
|
||||
fclose(f);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -310,13 +307,13 @@ static bool load_TGA(FileOp *fop)
|
||||
default:
|
||||
/* TODO add support for more TGA types? */
|
||||
|
||||
pack_fclose(f);
|
||||
fclose(f);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
image = fop_sequence_image(fop, type, image_width, image_height);
|
||||
if (!image) {
|
||||
pack_fclose(f);
|
||||
fclose(f);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -330,11 +327,11 @@ static bool load_TGA(FileOp *fop)
|
||||
if (compressed)
|
||||
rle_tga_read(image->line[yc], image_width, image_type, f);
|
||||
else if (image_type == 1)
|
||||
pack_fread(image->line[yc], image_width, f);
|
||||
fread(image->line[yc], 1, image_width, f);
|
||||
else {
|
||||
for (x=0; x<image_width; x++)
|
||||
*(((ase_uint16 **)image->line)[yc]+x) =
|
||||
_graya(pack_getc(f), 255);
|
||||
_graya(fgetc(f), 255);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -345,7 +342,7 @@ static bool load_TGA(FileOp *fop)
|
||||
}
|
||||
else {
|
||||
for (x=0; x<image_width; x++) {
|
||||
pack_fread(rgb, 4, f);
|
||||
fread(rgb, 1, 4, f);
|
||||
*(((ase_uint32 **)image->line)[yc]+x) =
|
||||
_rgba(rgb[2], rgb[1], rgb[0], rgb[3]);
|
||||
}
|
||||
@ -357,7 +354,7 @@ static bool load_TGA(FileOp *fop)
|
||||
}
|
||||
else {
|
||||
for (x=0; x<image_width; x++) {
|
||||
pack_fread(rgb, 3, f);
|
||||
fread(rgb, 1, 3, f);
|
||||
*(((ase_uint32 **)image->line)[yc]+x) =
|
||||
_rgba(rgb[2], rgb[1], rgb[0], 255);
|
||||
}
|
||||
@ -369,7 +366,7 @@ static bool load_TGA(FileOp *fop)
|
||||
}
|
||||
else {
|
||||
for (x=0; x<image_width; x++) {
|
||||
c = pack_igetw(f);
|
||||
c = fgetw(f);
|
||||
*(((ase_uint32 **)image->line)[yc]+x) =
|
||||
_rgba(((c >> 10) & 0x1F),
|
||||
((c >> 5) & 0x1F),
|
||||
@ -380,18 +377,22 @@ static bool load_TGA(FileOp *fop)
|
||||
break;
|
||||
}
|
||||
|
||||
if (image_height > 1)
|
||||
if (image_height > 1) {
|
||||
fop_progress(fop, (float)(image_height-y) / (float)(image_height));
|
||||
if (fop_is_stop(fop))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (*allegro_errno) {
|
||||
fop_error(fop, _("Error reading bytes.\n"));
|
||||
pack_fclose(f);
|
||||
if (ferror(f)) {
|
||||
fop_error(fop, _("Error reading file.\n"));
|
||||
fclose(f);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pack_fclose(f);
|
||||
return TRUE;
|
||||
else {
|
||||
fclose(f);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* save_tga:
|
||||
@ -405,33 +406,31 @@ static bool save_TGA(FileOp *fop)
|
||||
int x, y, c, r, g, b;
|
||||
int depth = (image->imgtype == IMAGE_RGB) ? 32 : 8;
|
||||
bool need_pal = (image->imgtype == IMAGE_INDEXED)? TRUE: FALSE;
|
||||
PACKFILE *f;
|
||||
FILE *f;
|
||||
|
||||
f = pack_fopen(fop->filename, F_WRITE);
|
||||
f = fopen(fop->filename, "wb");
|
||||
if (!f) {
|
||||
fop_error(fop, _("Error creating file.\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*allegro_errno = 0;
|
||||
|
||||
pack_putc(0, f); /* id length (no id saved) */
|
||||
pack_putc((need_pal) ? 1 : 0, f); /* palette type */
|
||||
fputc(0, f); /* id length (no id saved) */
|
||||
fputc((need_pal) ? 1 : 0, f); /* palette type */
|
||||
/* image type */
|
||||
pack_putc((image->imgtype == IMAGE_RGB ) ? 2 :
|
||||
(image->imgtype == IMAGE_GRAYSCALE) ? 3 :
|
||||
(image->imgtype == IMAGE_INDEXED ) ? 1 : 0, f);
|
||||
pack_iputw(0, f); /* first colour */
|
||||
pack_iputw((need_pal) ? 256 : 0, f); /* number of colours */
|
||||
pack_putc((need_pal) ? 24 : 0, f); /* palette entry size */
|
||||
pack_iputw(0, f); /* left */
|
||||
pack_iputw(0, f); /* top */
|
||||
pack_iputw(image->w, f); /* width */
|
||||
pack_iputw(image->h, f); /* height */
|
||||
pack_putc(depth, f); /* bits per pixel */
|
||||
fputc((image->imgtype == IMAGE_RGB ) ? 2 :
|
||||
(image->imgtype == IMAGE_GRAYSCALE) ? 3 :
|
||||
(image->imgtype == IMAGE_INDEXED ) ? 1 : 0, f);
|
||||
fputw(0, f); /* first colour */
|
||||
fputw((need_pal) ? 256 : 0, f); /* number of colours */
|
||||
fputc((need_pal) ? 24 : 0, f); /* palette entry size */
|
||||
fputw(0, f); /* left */
|
||||
fputw(0, f); /* top */
|
||||
fputw(image->w, f); /* width */
|
||||
fputw(image->h, f); /* height */
|
||||
fputc(depth, f); /* bits per pixel */
|
||||
|
||||
/* descriptor (bottom to top, 8-bit alpha) */
|
||||
pack_putc(image->imgtype == IMAGE_RGB ? 8: 0, f);
|
||||
fputc(image->imgtype == IMAGE_RGB ? 8: 0, f);
|
||||
|
||||
if (need_pal) {
|
||||
for (y=0; y<256; y++) {
|
||||
@ -440,7 +439,7 @@ static bool save_TGA(FileOp *fop)
|
||||
image_palette[y][1] = _rgb_scale_6[g];
|
||||
image_palette[y][0] = _rgb_scale_6[b];
|
||||
}
|
||||
pack_fwrite(image_palette, 768, f);
|
||||
fwrite(image_palette, 1, 768, f);
|
||||
}
|
||||
|
||||
switch (image->imgtype) {
|
||||
@ -449,10 +448,10 @@ static bool save_TGA(FileOp *fop)
|
||||
for (y=image->h-1; y>=0; y--) {
|
||||
for (x=0; x<image->w; x++) {
|
||||
c = image_getpixel(image, x, y);
|
||||
pack_putc(_rgba_getb(c), f);
|
||||
pack_putc(_rgba_getg(c), f);
|
||||
pack_putc(_rgba_getr(c), f);
|
||||
pack_putc(_rgba_geta(c), f);
|
||||
fputc(_rgba_getb(c), f);
|
||||
fputc(_rgba_getg(c), f);
|
||||
fputc(_rgba_getr(c), f);
|
||||
fputc(_rgba_geta(c), f);
|
||||
}
|
||||
|
||||
fop_progress(fop, (float)(image->h-y) / (float)(image->h));
|
||||
@ -462,7 +461,7 @@ static bool save_TGA(FileOp *fop)
|
||||
case IMAGE_GRAYSCALE:
|
||||
for (y=image->h-1; y>=0; y--) {
|
||||
for (x=0; x<image->w; x++)
|
||||
pack_putc(_graya_getk(image_getpixel(image, x, y)), f);
|
||||
fputc(_graya_getk(image_getpixel(image, x, y)), f);
|
||||
|
||||
fop_progress(fop, (float)(image->h-y) / (float)(image->h));
|
||||
}
|
||||
@ -471,19 +470,20 @@ static bool save_TGA(FileOp *fop)
|
||||
case IMAGE_INDEXED:
|
||||
for (y=image->h-1; y>=0; y--) {
|
||||
for (x=0; x<image->w; x++)
|
||||
pack_putc(image_getpixel(image, x, y), f);
|
||||
fputc(image_getpixel(image, x, y), f);
|
||||
|
||||
fop_progress(fop, (float)(image->h-y) / (float)(image->h));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
pack_fclose(f);
|
||||
|
||||
if (*allegro_errno) {
|
||||
fop_error(fop, _("Error writing bytes.\n"));
|
||||
if (ferror(f)) {
|
||||
fop_error(fop, _("Error writing file.\n"));
|
||||
fclose(f);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
else {
|
||||
fclose(f);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
10
src/main.c
10
src/main.c
@ -1,5 +1,5 @@
|
||||
/* ASE - Allegro Sprite Editor
|
||||
* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2008 David A. Capello
|
||||
* Copyright (C) 2001-2008 David A. 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
|
||||
@ -43,6 +43,10 @@ int main(int argc, char *argv[])
|
||||
/* set_uformat(U_UTF8); */
|
||||
set_uformat(U_ASCII);
|
||||
|
||||
#if defined MEMLEAK
|
||||
jmemleak_init();
|
||||
#endif
|
||||
|
||||
/* initialises the application */
|
||||
if (!app_init(argc, argv))
|
||||
return 1;
|
||||
@ -50,6 +54,10 @@ int main(int argc, char *argv[])
|
||||
app_loop();
|
||||
app_exit();
|
||||
|
||||
#if defined MEMLEAK
|
||||
jmemleak_exit();
|
||||
#endif
|
||||
|
||||
allegro_exit();
|
||||
return 0;
|
||||
}
|
||||
|
@ -558,6 +558,24 @@ void rectshade(BITMAP *bmp, int x1, int y1, int x2, int y2, int top, int bottom)
|
||||
}
|
||||
}
|
||||
|
||||
void draw_emptyset_symbol(JRect rc, int color)
|
||||
{
|
||||
int cx, cy, x1, y1, x2, y2, size;
|
||||
|
||||
size = MIN(jrect_w(rc), jrect_h(rc)) - 8;
|
||||
size = MID(4, size, 64);
|
||||
|
||||
cx = (rc->x1+rc->x2)/2;
|
||||
cy = (rc->y1+rc->y2)/2;
|
||||
x1 = cx-size/2;
|
||||
y1 = cy-size/2;
|
||||
x2 = x1+size-1;
|
||||
y2 = y1+size-1;
|
||||
|
||||
circle(ji_screen, cx, cy, size/2, color);
|
||||
line(ji_screen, x1, y2, x2, y1, color);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
|
@ -19,6 +19,8 @@
|
||||
#ifndef MODULES_GFX_H
|
||||
#define MODULES_GFX_H
|
||||
|
||||
#include "jinete/jbase.h"
|
||||
|
||||
struct FONT;
|
||||
struct BITMAP;
|
||||
|
||||
@ -113,6 +115,8 @@ void rectgrid(struct BITMAP *bmp, int x1, int y1, int x2, int y2, int w, int h);
|
||||
void rectfill_exclude(struct BITMAP *bmp, int x1, int y1, int x2, int y2, int ex1, int ey1, int ex2, int ey2, int color);
|
||||
void rectshade(struct BITMAP *bmp, int x1, int y1, int x2, int y2, int top, int bottom);
|
||||
|
||||
void draw_emptyset_symbol(JRect rc, int color);
|
||||
|
||||
int character_length(struct FONT *font, int chr);
|
||||
void render_character(struct BITMAP *bmp, struct FONT *font, int chr, int x, int y, int fg, int bg);
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* ASE - Allegro Sprite Editor
|
||||
* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007,
|
||||
* 2008 David A. Capello
|
||||
* Copyright (C) 2001-2008 David A. 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
|
||||
@ -21,6 +20,7 @@
|
||||
|
||||
#ifndef USE_PRECOMPILED_HEADER
|
||||
|
||||
#include <assert.h>
|
||||
#include <allegro.h>
|
||||
#include <allegro/internal/aintern.h>
|
||||
|
||||
@ -65,7 +65,8 @@
|
||||
# define DEF_SCALE 1
|
||||
#endif
|
||||
|
||||
static struct {
|
||||
static struct
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
int scale;
|
||||
@ -80,17 +81,26 @@ static int try_depths[] = { 32, 24, 16, 15, 8 };
|
||||
|
||||
/**************************************************************/
|
||||
|
||||
typedef struct Monitor {
|
||||
/**
|
||||
* Returns true when the job is done and the monitor can be removed.
|
||||
*/
|
||||
bool (*proc)(void *);
|
||||
typedef struct ExitHook
|
||||
{
|
||||
void (*proc)(void *);
|
||||
void *data;
|
||||
bool lock;
|
||||
} Monitor;
|
||||
} ExitHook;
|
||||
|
||||
struct Monitor
|
||||
{
|
||||
/* returns true when the job is done and the monitor can be removed */
|
||||
void (*proc)(void *);
|
||||
void (*free)(void *);
|
||||
void *data;
|
||||
bool lock : 1;
|
||||
bool deleted : 1;
|
||||
};
|
||||
|
||||
static JWidget manager = NULL;
|
||||
|
||||
static JList exit_hooks;
|
||||
|
||||
static int monitor_timer = -1;
|
||||
static JList monitors;
|
||||
|
||||
@ -103,7 +113,11 @@ static JList icon_buttons;
|
||||
static bool double_buffering;
|
||||
static int screen_scaling;
|
||||
|
||||
static Monitor *monitor_new(bool (*proc)(void *), void *data);
|
||||
static ExitHook *exithook_new(void (*proc)(void *), void *data);
|
||||
static void exithook_free(ExitHook *exithook);
|
||||
|
||||
static Monitor *monitor_new(void (*proc)(void *),
|
||||
void (*free)(void *), void *data);
|
||||
static void monitor_free(Monitor *monitor);
|
||||
|
||||
/* load & save graphics configuration */
|
||||
@ -236,6 +250,7 @@ int init_module_gui(void)
|
||||
}
|
||||
gfx_done:;
|
||||
|
||||
exit_hooks = jlist_new();
|
||||
monitors = jlist_new();
|
||||
|
||||
/* create the default-manager */
|
||||
@ -279,6 +294,16 @@ void exit_module_gui(void)
|
||||
{
|
||||
JLink link;
|
||||
|
||||
/* call the ExitHooks */
|
||||
JI_LIST_FOR_EACH(exit_hooks, link) {
|
||||
ExitHook *exithook = link->data;
|
||||
(*exithook->proc)(exithook->data);
|
||||
exithook_free(link->data);
|
||||
}
|
||||
jlist_free(exit_hooks);
|
||||
exit_hooks = NULL;
|
||||
|
||||
/* destroy monitors */
|
||||
JI_LIST_FOR_EACH(monitors, link) {
|
||||
monitor_free(link->data);
|
||||
}
|
||||
@ -305,21 +330,44 @@ void exit_module_gui(void)
|
||||
remove_timer();
|
||||
}
|
||||
|
||||
static Monitor *monitor_new(bool (*proc)(void *), void *data)
|
||||
static ExitHook *exithook_new(void (*proc)(void *), void *data)
|
||||
{
|
||||
ExitHook *exithook = jnew(ExitHook, 1);
|
||||
if (!exithook)
|
||||
return NULL;
|
||||
|
||||
exithook->proc = proc;
|
||||
exithook->data = data;
|
||||
|
||||
return exithook;
|
||||
}
|
||||
|
||||
static void exithook_free(ExitHook *exithook)
|
||||
{
|
||||
jfree(exithook);
|
||||
}
|
||||
|
||||
static Monitor *monitor_new(void (*proc)(void *),
|
||||
void (*free)(void *), void *data)
|
||||
{
|
||||
Monitor *monitor = jnew(Monitor, 1);
|
||||
if (!monitor)
|
||||
return NULL;
|
||||
|
||||
monitor->proc = proc;
|
||||
monitor->free = free;
|
||||
monitor->data = data;
|
||||
monitor->lock = FALSE;
|
||||
monitor->deleted = FALSE;
|
||||
|
||||
return monitor;
|
||||
}
|
||||
|
||||
static void monitor_free(Monitor *monitor)
|
||||
{
|
||||
if (monitor->free)
|
||||
(*monitor->free)(monitor->data);
|
||||
|
||||
jfree(monitor);
|
||||
}
|
||||
|
||||
@ -721,14 +769,53 @@ JWidget check_button_new(const char *text, int b1, int b2, int b3, int b4)
|
||||
return widget;
|
||||
}
|
||||
|
||||
void add_gui_monitor(bool (*proc)(void *data), void *data)
|
||||
/**
|
||||
* Adds a routine to be called when the @ref exit_module_gui is called.
|
||||
*/
|
||||
void add_gui_exit_hook(void (*proc)(void *data), void *data)
|
||||
{
|
||||
jlist_append(monitors, monitor_new(proc, data));
|
||||
assert(proc != NULL);
|
||||
assert(exit_hooks != NULL);
|
||||
|
||||
jlist_append(exit_hooks, exithook_new(proc, data));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a routine to be called each 100 milliseconds to monitor
|
||||
* whatever you want. It's mainly used to monitor the progress of a
|
||||
* file-operation (see @ref fop_operate)
|
||||
*/
|
||||
Monitor *add_gui_monitor(void (*proc)(void *),
|
||||
void (*free)(void *), void *data)
|
||||
{
|
||||
Monitor *monitor = monitor_new(proc, free, data);
|
||||
|
||||
jlist_append(monitors, monitor);
|
||||
|
||||
if (monitor_timer < 0)
|
||||
monitor_timer = jmanager_add_timer(manager, 100);
|
||||
|
||||
jmanager_start_timer(monitor_timer);
|
||||
|
||||
return monitor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a previously added monitor.
|
||||
*/
|
||||
void remove_gui_monitor(Monitor *monitor)
|
||||
{
|
||||
JLink link = jlist_find(monitors, monitor);
|
||||
assert(link != NULL);
|
||||
|
||||
if (!monitor->lock)
|
||||
monitor_free(monitor);
|
||||
else
|
||||
monitor->deleted = TRUE;
|
||||
|
||||
jlist_delete_link(monitors, link);
|
||||
if (jlist_empty(monitors))
|
||||
jmanager_stop_timer(monitor_timer);
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
@ -752,13 +839,11 @@ static bool manager_msg_proc(JWidget widget, JMessage msg)
|
||||
if (!monitor->lock) {
|
||||
/* call the monitor procedure */
|
||||
monitor->lock = TRUE;
|
||||
if ((*monitor->proc)(monitor->data)) {
|
||||
/* the function returns true, the job is done... remove the monitor */
|
||||
monitor_free(link->data);
|
||||
jlist_delete_link(monitors, link);
|
||||
}
|
||||
else
|
||||
monitor->lock = FALSE;
|
||||
(*monitor->proc)(monitor->data);
|
||||
monitor->lock = FALSE;
|
||||
|
||||
if (monitor->deleted)
|
||||
monitor_free(monitor);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* ASE - Allegro Sprite Editor
|
||||
* Copyright (C) 2001-2005, 2007, 2008 David A. Capello
|
||||
* Copyright (C) 2001-2008 David A. 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
|
||||
@ -25,6 +25,9 @@
|
||||
hook_signal((widget), (signal), (signal_handler), (int)(user_data))
|
||||
|
||||
struct Sprite;
|
||||
struct Monitor;
|
||||
|
||||
typedef struct Monitor Monitor;
|
||||
|
||||
int init_module_gui(void);
|
||||
void exit_module_gui(void);
|
||||
@ -61,6 +64,16 @@ JWidget radio_button_new(int radio_group, int b1, int b2, int b3, int b4);
|
||||
JWidget check_button_new(const char *text, int b1, int b2, int b3, int b4);
|
||||
/* void change_to_button_style(JWidget widget, int b1, int b2, int b3, int b4); */
|
||||
|
||||
void add_gui_monitor(bool (*proc)(void *data), void *data);
|
||||
/********************************************************************/
|
||||
/* exit-hooks */
|
||||
|
||||
void add_gui_exit_hook(void (*proc)(void *data), void *data);
|
||||
|
||||
/********************************************************************/
|
||||
/* monitors */
|
||||
|
||||
Monitor *add_gui_monitor(void (*proc)(void *),
|
||||
void (*free)(void *), void *data);
|
||||
void remove_gui_monitor(Monitor *monitor);
|
||||
|
||||
#endif /* MODULES_GUI_H */
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* ASE - Allegro Sprite Editor
|
||||
* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007,
|
||||
* 2008 David A. Capello
|
||||
* Copyright (C) 2001-2008 David A. 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
|
||||
@ -54,19 +53,18 @@ static void apply_shortcut_to_menuitems_with_command(JWidget menu, Command *comm
|
||||
|
||||
int init_module_rootmenu(void)
|
||||
{
|
||||
root_menu = 0;
|
||||
root_menu = NULL;
|
||||
layer_popup_menu = NULL;
|
||||
frame_popup_menu = NULL;
|
||||
cel_popup_menu = NULL;
|
||||
filters_popup_menu = NULL;
|
||||
recent_list_menuitem = NULL;
|
||||
|
||||
return load_root_menu();
|
||||
}
|
||||
|
||||
void exit_module_rootmenu(void)
|
||||
{
|
||||
recent_list_menuitem = NULL;
|
||||
layer_popup_menu = NULL;
|
||||
frame_popup_menu = NULL;
|
||||
cel_popup_menu = NULL;
|
||||
filters_popup_menu = NULL;
|
||||
|
||||
command_reset_keys();
|
||||
jwidget_free(root_menu);
|
||||
|
||||
@ -231,10 +229,10 @@ static JWidget load_menu_by_id(JXml xml, const char *id, const char *filename)
|
||||
menu = convert_xmlelem_to_menu(elem);
|
||||
}
|
||||
else
|
||||
PRINTF("Invalid element with id=\"main_menu\" in \"%s\"\n", filename);
|
||||
PRINTF("Invalid element with id=\"%s\" in \"%s\"\n", id, filename);
|
||||
}
|
||||
else
|
||||
PRINTF("\"main_menu\" element couldn't be found...\n");
|
||||
PRINTF("\"%s\" element couldn't be found...\n", id);
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* ASE - Allegro Sprite Editor
|
||||
* Copyright (C) 2001-2005, 2007, 2008 David A. Capello
|
||||
* Copyright (C) 2001-2008 David A. 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
|
||||
@ -63,11 +63,16 @@ int init_module_sprites(void)
|
||||
|
||||
void exit_module_sprites(void)
|
||||
{
|
||||
JLink link;
|
||||
|
||||
if (clipboard_sprite) {
|
||||
sprite_free(clipboard_sprite);
|
||||
clipboard_sprite = NULL;
|
||||
}
|
||||
|
||||
JI_LIST_FOR_EACH(sprites_list, link) {
|
||||
sprite_free(link->data);
|
||||
}
|
||||
jlist_free(sprites_list);
|
||||
sprites_list = NULL;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* ASE - Allegro Sprite Editor
|
||||
* Copyright (C) 2001-2005, 2007 David A. Capello
|
||||
* Copyright (C) 2001-2008 David A. 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
|
||||
@ -22,53 +22,53 @@
|
||||
#define BYTES(image) ((ase_uint32 *)image->dat)
|
||||
#define LINES(image) ((ase_uint32 **)image->line)
|
||||
|
||||
static int rgb_regenerate_lines (Image *image)
|
||||
static int rgb_regenerate_lines(Image *image)
|
||||
{
|
||||
ase_uint32 *address = BYTES (image);
|
||||
ase_uint32 *address = BYTES(image);
|
||||
int y;
|
||||
|
||||
if (LINES (image))
|
||||
jfree (LINES (image));
|
||||
if (LINES(image))
|
||||
jfree (LINES(image));
|
||||
|
||||
image->line = jmalloc(sizeof(ase_uint32 *) * image->h);
|
||||
if (!LINES (image))
|
||||
if (!LINES(image))
|
||||
return -1;
|
||||
|
||||
for (y=0; y<image->h; y++) {
|
||||
LINES (image)[y] = address;
|
||||
LINES(image)[y] = address;
|
||||
address += image->w;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rgb_init (Image *image)
|
||||
static int rgb_init(Image *image)
|
||||
{
|
||||
image->dat = jmalloc(sizeof(ase_uint32) * image->w * image->h);
|
||||
if (!BYTES (image))
|
||||
if (!BYTES(image))
|
||||
return -1;
|
||||
|
||||
if (rgb_regenerate_lines (image) < 0) {
|
||||
jfree (BYTES (image));
|
||||
if (rgb_regenerate_lines(image) < 0) {
|
||||
jfree(BYTES(image));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rgb_getpixel (const Image *image, int x, int y)
|
||||
static int rgb_getpixel(const Image *image, int x, int y)
|
||||
{
|
||||
return *(LINES (image)[y]+x);
|
||||
return *(LINES(image)[y]+x);
|
||||
}
|
||||
|
||||
static void rgb_putpixel (Image *image, int x, int y, int color)
|
||||
static void rgb_putpixel(Image *image, int x, int y, int color)
|
||||
{
|
||||
*(LINES (image)[y]+x) = color;
|
||||
*(LINES(image)[y]+x) = color;
|
||||
}
|
||||
|
||||
static void rgb_clear (Image *image, int color)
|
||||
static void rgb_clear(Image *image, int color)
|
||||
{
|
||||
ase_uint32 *address = BYTES (image);
|
||||
ase_uint32 *address = BYTES(image);
|
||||
unsigned int c, size = image->w * image->h;
|
||||
|
||||
for (c=0; c<size; c++)
|
||||
@ -118,15 +118,15 @@ static void rgb_copy(Image *dst, const Image *src, int x, int y)
|
||||
bytes = (xend - xbeg + 1) << 2;
|
||||
|
||||
for (ydst=ybeg; ydst<=yend; ydst++, ysrc++) {
|
||||
src_address = LINES (src)[ysrc]+xsrc;
|
||||
dst_address = LINES (dst)[ydst]+xbeg;
|
||||
src_address = LINES(src)[ysrc]+xsrc;
|
||||
dst_address = LINES(dst)[ydst]+xbeg;
|
||||
|
||||
memcpy (dst_address, src_address, bytes);
|
||||
memcpy(dst_address, src_address, bytes);
|
||||
}
|
||||
}
|
||||
|
||||
static void rgb_merge (Image *dst, const Image *src,
|
||||
int x, int y, int opacity, int blend_mode)
|
||||
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;
|
||||
@ -171,11 +171,11 @@ static void rgb_merge (Image *dst, const Image *src,
|
||||
/* merge process */
|
||||
|
||||
for (ydst=ybeg; ydst<=yend; ydst++, ysrc++) {
|
||||
src_address = LINES (src)[ysrc]+xsrc;
|
||||
dst_address = LINES (dst)[ydst]+xbeg;
|
||||
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 = (*blender)(*dst_address, *src_address, opacity);
|
||||
|
||||
dst_address++;
|
||||
src_address++;
|
||||
@ -183,28 +183,28 @@ static void rgb_merge (Image *dst, const Image *src,
|
||||
}
|
||||
}
|
||||
|
||||
static void rgb_hline (Image *image, int x1, int y, int x2, int color)
|
||||
static void rgb_hline(Image *image, int x1, int y, int x2, int color)
|
||||
{
|
||||
ase_uint32 *address = LINES (image)[y]+x1;
|
||||
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)
|
||||
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;
|
||||
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)
|
||||
static void rgb_to_allegro(const Image *image, BITMAP *bmp, int _x, int _y)
|
||||
{
|
||||
ase_uint32 *address = BYTES(image);
|
||||
unsigned long bmp_address;
|
||||
@ -332,7 +332,7 @@ static void rgb_to_allegro (const Image *image, BITMAP *bmp, int _x, int _y)
|
||||
break;
|
||||
}
|
||||
|
||||
bmp_unwrite_line (bmp);
|
||||
bmp_unwrite_line(bmp);
|
||||
}
|
||||
|
||||
static ImageMethods rgb_methods =
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* ASE - Allegro Sprite Editor
|
||||
* Copyright (C) 2001-2005, 2007, 2008 David A. Capello
|
||||
* Copyright (C) 2001-2008 David A. 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
|
||||
@ -162,6 +162,7 @@ void layer_free(Layer *layer)
|
||||
JLink link;
|
||||
JI_LIST_FOR_EACH(layer->layers, link)
|
||||
layer_free(link->data);
|
||||
jlist_free(layer->layers);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* ASE - Allegro Sprite Editor
|
||||
* Copyright (C) 2001-2005, 2007 David A. Capello
|
||||
* Copyright (C) 2001-2008 David A. 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
|
||||
@ -1163,14 +1163,10 @@ static void chunk_set_mask_invert(UndoStream *stream, UndoChunk *chunk, int stat
|
||||
if (sprite) {
|
||||
Mask *mask = undo_chunk_read_mask(chunk);
|
||||
|
||||
/* ji_assert(mask); */
|
||||
|
||||
chunk_set_mask(stream, sprite);
|
||||
mask_copy(sprite->mask, mask);
|
||||
|
||||
/* change the sprite mask directly */
|
||||
/* mask_free(sprite->mask); */
|
||||
/* sprite->mask = mask; */
|
||||
mask_free(mask);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* ASE - Allegro Sprite Editor
|
||||
* Copyright (C) 2001-2005, 2007, 2008 David A. Capello
|
||||
* Copyright (C) 2001-2008 David A. 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
|
||||
|
55
src/test/test_errno.c
Normal file
55
src/test/test_errno.c
Normal file
@ -0,0 +1,55 @@
|
||||
/* ASE - Allegro Sprite Editor
|
||||
* Copyright (C) 2001-2008 David A. 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 "test/test.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <allegro.h>
|
||||
|
||||
#include "jinete/jthread.h"
|
||||
|
||||
static JThread thread;
|
||||
|
||||
static void run_thread(void *data)
|
||||
{
|
||||
errno = 0;
|
||||
trace("[second thread] errno: %d\n", errno);
|
||||
assert(errno == 0);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
allegro_init();
|
||||
|
||||
errno = 1;
|
||||
trace("[main thread] errno: %d\n", errno);
|
||||
assert(errno == 1);
|
||||
|
||||
thread = jthread_new(run_thread, NULL);
|
||||
jthread_join(thread);
|
||||
|
||||
trace("[main thread] errno: %d\n", errno);
|
||||
assert(errno == 1);
|
||||
|
||||
trace("OK: errno is thread safe\n");
|
||||
|
||||
allegro_exit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
END_OF_MAIN();
|
@ -1,5 +1,5 @@
|
||||
/* ASE - Allegro Sprite Editor
|
||||
* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2008 David A. Capello
|
||||
* Copyright (C) 2001-2008 David A. 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
|
||||
|
@ -20,8 +20,10 @@
|
||||
|
||||
#ifndef USE_PRECOMPILED_HEADER
|
||||
|
||||
#include <stdio.h>
|
||||
#include <allegro.h>
|
||||
|
||||
#include "file/file.h"
|
||||
#include "raster/image.h"
|
||||
|
||||
#endif
|
||||
@ -40,12 +42,12 @@ RGB *load_col_file(const char *filename)
|
||||
div_t d = div(size-8, 3);
|
||||
RGB *palette = NULL;
|
||||
int c, r, g, b;
|
||||
PACKFILE *f;
|
||||
FILE *f;
|
||||
|
||||
if (!(size) || (pro && d.rem)) /* invalid format */
|
||||
return NULL;
|
||||
|
||||
f = pack_fopen(filename, F_READ);
|
||||
f = fopen(filename, "rb");
|
||||
if (!f)
|
||||
return NULL;
|
||||
|
||||
@ -54,9 +56,9 @@ RGB *load_col_file(const char *filename)
|
||||
palette = jmalloc(sizeof (PALETTE));
|
||||
|
||||
for (c=0; c<256; c++) {
|
||||
r = pack_getc(f);
|
||||
g = pack_getc(f);
|
||||
b = pack_getc(f);
|
||||
r = fgetc(f);
|
||||
g = fgetc(f);
|
||||
b = fgetc(f);
|
||||
palette[c].r = MID(0, r, 63);
|
||||
palette[c].g = MID(0, g, 63);
|
||||
palette[c].b = MID(0, b, 63);
|
||||
@ -66,22 +68,22 @@ RGB *load_col_file(const char *filename)
|
||||
else {
|
||||
int magic, version;
|
||||
|
||||
pack_igetl(f); /* skip file size */
|
||||
magic = pack_igetw(f); /* file format identifier */
|
||||
version = pack_igetw(f); /* version file */
|
||||
fgetl(f); /* skip file size */
|
||||
magic = fgetw(f); /* file format identifier */
|
||||
version = fgetw(f); /* version file */
|
||||
|
||||
/* unknown format */
|
||||
if (magic != 0xB123 || version != 0) {
|
||||
pack_fclose (f);
|
||||
fclose (f);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
palette = jmalloc(sizeof (PALETTE));
|
||||
|
||||
for (c=0; c<d.quot && c<256; c++) {
|
||||
r = pack_getc(f);
|
||||
g = pack_getc(f);
|
||||
b = pack_getc(f);
|
||||
r = fgetc(f);
|
||||
g = fgetc(f);
|
||||
b = fgetc(f);
|
||||
palette[c].r = MID(0, r, 255)>>2;
|
||||
palette[c].g = MID(0, g, 255)>>2;
|
||||
palette[c].b = MID(0, b, 255)>>2;
|
||||
@ -91,30 +93,30 @@ RGB *load_col_file(const char *filename)
|
||||
palette[c].r = palette[c].g = palette[c].b = 0;
|
||||
}
|
||||
|
||||
pack_fclose(f);
|
||||
fclose(f);
|
||||
return palette;
|
||||
}
|
||||
|
||||
/* saves an Animator Pro COL file */
|
||||
int save_col_file(RGB *palette, const char *filename)
|
||||
{
|
||||
PACKFILE *f;
|
||||
FILE *f;
|
||||
int c;
|
||||
|
||||
f = pack_fopen(filename, F_WRITE);
|
||||
f = fopen(filename, "wb");
|
||||
if (!f)
|
||||
return -1;
|
||||
|
||||
pack_iputl(8+768, f); /* file size */
|
||||
pack_iputw(0xB123, f); /* file format identifier */
|
||||
pack_iputw(0, f); /* version file */
|
||||
fputl(8+768, f); /* file size */
|
||||
fputw(0xB123, f); /* file format identifier */
|
||||
fputw(0, f); /* version file */
|
||||
|
||||
for (c=0; c<256; c++) {
|
||||
pack_putc(_rgb_scale_6[palette[c].r], f);
|
||||
pack_putc(_rgb_scale_6[palette[c].g], f);
|
||||
pack_putc(_rgb_scale_6[palette[c].b], f);
|
||||
fputc(_rgb_scale_6[palette[c].r], f);
|
||||
fputc(_rgb_scale_6[palette[c].g], f);
|
||||
fputc(_rgb_scale_6[palette[c].b], f);
|
||||
}
|
||||
|
||||
pack_fclose(f);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
@ -988,25 +988,10 @@ static bool editor_msg_proc(JWidget widget, JMessage msg)
|
||||
if (!editor->sprite) {
|
||||
JWidget view = jwidget_get_view(widget);
|
||||
JRect vp = jview_get_viewport_position(view);
|
||||
int size, x1, y1, x2, y2, cx, cy;
|
||||
int bg = makecol(128, 128, 128);
|
||||
int fg = makecol(64, 64, 64);
|
||||
|
||||
jdraw_rectfill(vp, bg);
|
||||
|
||||
size = MIN(jrect_w(vp), jrect_h(vp)) - 8;
|
||||
size = MID(4, size, 64);
|
||||
|
||||
cx = (vp->x1+vp->x2)/2;
|
||||
cy = (vp->y1+vp->y2)/2;
|
||||
x1 = (vp->x1+vp->x2)/2-size/2;
|
||||
y1 = (vp->y1+vp->y2)/2-size/2;
|
||||
x2 = x1+size-1;
|
||||
y2 = y1+size-1;
|
||||
|
||||
circle(ji_screen, cx, cy, size/2, fg);
|
||||
line(ji_screen, x1, y2, x2, y1, fg);
|
||||
|
||||
jdraw_rectfill(vp, makecol(128, 128, 128));
|
||||
draw_emptyset_symbol(vp, makecol(64, 64, 64));
|
||||
|
||||
jrect_free(vp);
|
||||
}
|
||||
/* draw the sprite */
|
||||
|
@ -18,17 +18,30 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef USE_PRECOMPILED_HEADER
|
||||
|
||||
#include <assert.h>
|
||||
#include <allegro.h>
|
||||
|
||||
#include "jinete/jinete.h"
|
||||
|
||||
#include "commands/commands.h"
|
||||
#include "console/console.h"
|
||||
#include "core/app.h"
|
||||
#include "dialogs/filesel.h"
|
||||
#include "file/file.h"
|
||||
#include "modules/editors.h"
|
||||
#include "modules/gfx.h"
|
||||
#include "modules/gui.h"
|
||||
#include "modules/palette.h"
|
||||
#include "modules/recent.h"
|
||||
#include "modules/sprites.h"
|
||||
#include "raster/image.h"
|
||||
#include "raster/rotate.h"
|
||||
#include "raster/sprite.h"
|
||||
#include "widgets/fileview.h"
|
||||
#include "widgets/statebar.h"
|
||||
|
||||
#endif
|
||||
#define MAX_THUMBNAIL_SIZE 128
|
||||
#define MAX_THREADS_TO_GEN_THUMBNAILS 1
|
||||
|
||||
typedef struct FileView
|
||||
{
|
||||
@ -38,8 +51,24 @@ typedef struct FileView
|
||||
int req_w, req_h;
|
||||
FileItem *selected;
|
||||
const char *exts;
|
||||
|
||||
/* round-robin thumbnail generation process */
|
||||
JLink item_to_generate_thumbnail; /* current item in the round-robin */
|
||||
int round_timer_id;
|
||||
JList monitors; /* list of monitors watching threads */
|
||||
} FileView;
|
||||
|
||||
typedef struct ThumbnailData
|
||||
{
|
||||
Monitor *monitor;
|
||||
FileOp *fop;
|
||||
FileItem *fileitem;
|
||||
JWidget fileview;
|
||||
Image *thumbnail;
|
||||
JThread thread;
|
||||
PALETTE pal;
|
||||
} ThumbnailData;
|
||||
|
||||
static FileView *fileview_data(JWidget widget);
|
||||
static bool fileview_msg_proc(JWidget widget, JMessage msg);
|
||||
static void fileview_get_fileitem_size(JWidget widget, FileItem *fi, int *w, int *h);
|
||||
@ -47,6 +76,13 @@ static void fileview_make_selected_fileitem_visible(JWidget widget);
|
||||
static void fileview_regenerate_list(JWidget widget);
|
||||
static int fileview_get_selected_index(JWidget widget);
|
||||
static void fileview_select_index(JWidget widget, int index);
|
||||
static void fileview_selected_item_to_generate_thumbnail(JWidget widget);
|
||||
static void fileview_generate_all_thumbnails(JWidget widget);
|
||||
static bool fileview_generate_thumbnail(JWidget widget, FileItem *fileitem);
|
||||
|
||||
static void openfile_bg(void *data);
|
||||
static void monitor_thumbnail_generation(void *data);
|
||||
static void monitor_free_thumbnail_generation(void *data);
|
||||
|
||||
JWidget fileview_new(FileItem *start_folder, const char *exts)
|
||||
{
|
||||
@ -72,6 +108,10 @@ JWidget fileview_new(FileItem *start_folder, const char *exts)
|
||||
fileview->selected = NULL;
|
||||
fileview->exts = exts;
|
||||
|
||||
fileview->item_to_generate_thumbnail = NULL;
|
||||
fileview->round_timer_id = jmanager_add_timer(widget, 200);
|
||||
fileview->monitors = jlist_new();
|
||||
|
||||
fileview_regenerate_list(widget);
|
||||
|
||||
return widget;
|
||||
@ -131,6 +171,23 @@ void fileview_goup(JWidget widget)
|
||||
}
|
||||
}
|
||||
|
||||
void fileview_stop_threads(JWidget widget)
|
||||
{
|
||||
FileView *fileview = fileview_data(widget);
|
||||
JLink link, next;
|
||||
|
||||
/* stop the generation of threads */
|
||||
jmanager_stop_timer(fileview->round_timer_id);
|
||||
|
||||
/* join all threads (removing all monitors) */
|
||||
JI_LIST_FOR_EACH_SAFE(fileview->monitors, link, next) {
|
||||
remove_gui_monitor(link->data);
|
||||
}
|
||||
|
||||
/* clear the list of monitors */
|
||||
jlist_clear(fileview->monitors);
|
||||
}
|
||||
|
||||
static FileView *fileview_data(JWidget widget)
|
||||
{
|
||||
return jwidget_get_data(widget, fileview_type());
|
||||
@ -143,6 +200,11 @@ static bool fileview_msg_proc(JWidget widget, JMessage msg)
|
||||
switch (msg->type) {
|
||||
|
||||
case JM_DESTROY:
|
||||
/* at this point, can't be threads running in background */
|
||||
assert(jlist_empty(fileview->monitors));
|
||||
|
||||
jlist_free(fileview->monitors);
|
||||
jmanager_remove_timer(fileview->round_timer_id);
|
||||
jfree(fileview);
|
||||
break;
|
||||
|
||||
@ -173,6 +235,8 @@ static bool fileview_msg_proc(JWidget widget, JMessage msg)
|
||||
return TRUE;
|
||||
|
||||
case JM_DRAW: {
|
||||
JWidget view = jwidget_get_view(widget);
|
||||
JRect vp = jview_get_viewport_position(view);
|
||||
FileItem *fi;
|
||||
JLink link;
|
||||
int iw, ih;
|
||||
@ -181,6 +245,8 @@ static bool fileview_msg_proc(JWidget widget, JMessage msg)
|
||||
int row = 0;
|
||||
int bgcolor;
|
||||
int fgcolor;
|
||||
BITMAP *thumbnail = NULL;
|
||||
int thumbnail_y;
|
||||
|
||||
jdraw_rectfill(widget->rc, makecol(255, 255, 255));
|
||||
|
||||
@ -217,14 +283,40 @@ static bool fileview_msg_proc(JWidget widget, JMessage msg)
|
||||
|
||||
x += ji_font_text_len(widget->text_font, "[+]")+2;
|
||||
}
|
||||
|
||||
|
||||
/* item name */
|
||||
jdraw_text(widget->text_font,
|
||||
fileitem_get_displayname(fi), x, y+2,
|
||||
fgcolor, 0, FALSE);
|
||||
|
||||
/* thumbnail position */
|
||||
if (fi == fileview->selected) {
|
||||
thumbnail = fileitem_get_thumbnail(fi);
|
||||
if (thumbnail)
|
||||
thumbnail_y = y + ih/2;
|
||||
}
|
||||
|
||||
y += ih;
|
||||
row ^= 1;
|
||||
}
|
||||
|
||||
/* draw the thumbnail */
|
||||
if (thumbnail) {
|
||||
x = vp->x2-2-thumbnail->w;
|
||||
y = thumbnail_y-thumbnail->h/2;
|
||||
y = MID(vp->y1+2, y, vp->y2-3-thumbnail->h);
|
||||
|
||||
draw_sprite(ji_screen, thumbnail, x, y);
|
||||
rect(ji_screen,
|
||||
x-1, y-1, x+thumbnail->w, y+thumbnail->h,
|
||||
makecol(0, 0, 0));
|
||||
}
|
||||
|
||||
/* is the current folder empty? */
|
||||
if (jlist_empty(fileview->list))
|
||||
draw_emptyset_symbol(vp, makecol(194, 194, 194));
|
||||
|
||||
jrect_free(vp);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -258,6 +350,8 @@ static bool fileview_msg_proc(JWidget widget, JMessage msg)
|
||||
}
|
||||
|
||||
if (old_selected != fileview->selected) {
|
||||
fileview_selected_item_to_generate_thumbnail(widget);
|
||||
|
||||
jwidget_dirty(widget);
|
||||
jwidget_emit_signal(widget, SIGNAL_FILEVIEW_FILE_SELECTED);
|
||||
}
|
||||
@ -370,6 +464,33 @@ static bool fileview_msg_proc(JWidget widget, JMessage msg)
|
||||
}
|
||||
break;
|
||||
|
||||
case JM_TIMER:
|
||||
/* is time to generate the next thumbnail in the round-robin? */
|
||||
if (msg->timer.timer_id == fileview->round_timer_id &&
|
||||
jlist_length(fileview->monitors) < MAX_THREADS_TO_GEN_THUMBNAILS) {
|
||||
JLink link = fileview->item_to_generate_thumbnail;
|
||||
JLink start = link;
|
||||
|
||||
while (link != fileview->list->end) {
|
||||
FileItem *fileitem = link->data;
|
||||
link = link->next != fileview->list->end ? link->next:
|
||||
link->next->next;
|
||||
|
||||
if (fileview_generate_thumbnail(widget, fileitem))
|
||||
break;
|
||||
|
||||
if (link == start)
|
||||
break;
|
||||
}
|
||||
|
||||
/* did we do all the round? */
|
||||
if (link == start)
|
||||
jmanager_stop_timer(fileview->round_timer_id);
|
||||
|
||||
fileview->item_to_generate_thumbnail = link;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
@ -457,6 +578,9 @@ static void fileview_regenerate_list(JWidget widget)
|
||||
}
|
||||
else
|
||||
fileview->list = jlist_new();
|
||||
|
||||
/* generate all thumbnails */
|
||||
fileview_generate_all_thumbnails(widget);
|
||||
}
|
||||
|
||||
static int fileview_get_selected_index(JWidget widget)
|
||||
@ -482,8 +606,183 @@ static void fileview_select_index(JWidget widget, int index)
|
||||
fileview->selected = jlist_nth_data(fileview->list, index);
|
||||
if (old_selected != fileview->selected) {
|
||||
fileview_make_selected_fileitem_visible(widget);
|
||||
|
||||
|
||||
jwidget_dirty(widget);
|
||||
jwidget_emit_signal(widget, SIGNAL_FILEVIEW_FILE_SELECTED);
|
||||
}
|
||||
|
||||
fileview_selected_item_to_generate_thumbnail(widget);
|
||||
}
|
||||
|
||||
/* puts the selected file-item as the next item to be processed by the
|
||||
round-robin that generate thumbnails */
|
||||
static void fileview_selected_item_to_generate_thumbnail(JWidget widget)
|
||||
{
|
||||
FileView *fileview = fileview_data(widget);
|
||||
|
||||
if (fileview->selected &&
|
||||
!fileitem_is_folder(fileview->selected) &&
|
||||
!fileitem_get_thumbnail(fileview->selected)) {
|
||||
fileview->item_to_generate_thumbnail =
|
||||
jlist_find(fileview->list, fileview->selected);
|
||||
}
|
||||
}
|
||||
|
||||
static void fileview_generate_all_thumbnails(JWidget widget)
|
||||
{
|
||||
FileView *fileview = fileview_data(widget);
|
||||
|
||||
fileview->item_to_generate_thumbnail = jlist_first(fileview->list);
|
||||
|
||||
jmanager_start_timer(fileview->round_timer_id);
|
||||
}
|
||||
|
||||
/* returns true if it does some hard work like access to the disk */
|
||||
static bool fileview_generate_thumbnail(JWidget widget, FileItem *fileitem)
|
||||
{
|
||||
FileOp *fop;
|
||||
|
||||
if (fileitem_is_browsable(fileitem) ||
|
||||
fileitem_get_thumbnail(fileitem) != NULL)
|
||||
return FALSE;
|
||||
|
||||
fop = fop_to_load_sprite(fileitem_get_filename(fileitem),
|
||||
FILE_LOAD_SEQUENCE_NONE |
|
||||
FILE_LOAD_ONE_FRAME);
|
||||
if (!fop)
|
||||
return TRUE;
|
||||
|
||||
if (fop->error) {
|
||||
fop_free(fop);
|
||||
}
|
||||
else {
|
||||
ThumbnailData *data = jnew(ThumbnailData, 1);
|
||||
|
||||
data->fop = fop;
|
||||
data->fileitem = fileitem;
|
||||
data->fileview = widget;
|
||||
data->thumbnail = NULL;
|
||||
|
||||
data->thread = jthread_new(openfile_bg, data);
|
||||
if (data->thread) {
|
||||
/* add a monitor to check the loading (FileOp) progress */
|
||||
data->monitor = add_gui_monitor(monitor_thumbnail_generation,
|
||||
monitor_free_thumbnail_generation, data);
|
||||
|
||||
jlist_append(fileview_data(widget)->monitors, data->monitor);
|
||||
}
|
||||
else {
|
||||
fop_free(fop);
|
||||
jfree(data);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Thread to do the hard work: load the file from the disk (in
|
||||
* background).
|
||||
*
|
||||
* [loading thread]
|
||||
*/
|
||||
static void openfile_bg(void *_data)
|
||||
{
|
||||
ThumbnailData *data = (ThumbnailData *)_data;
|
||||
FileOp *fop = (FileOp *)data->fop;
|
||||
Sprite *sprite;
|
||||
int thumb_w, thumb_h;
|
||||
Image *image;
|
||||
|
||||
/* load the file */
|
||||
fop_operate(fop);
|
||||
|
||||
sprite = fop->sprite;
|
||||
if (sprite) {
|
||||
if (fop_is_stop(fop))
|
||||
sprite_free(fop->sprite);
|
||||
else {
|
||||
/* the palette to convert the Image to a BITMAP */
|
||||
palette_copy(data->pal, sprite_get_palette(sprite, 0));
|
||||
|
||||
/* render the 'sprite' in one plain 'image' */
|
||||
image = image_new(sprite->imgtype, sprite->w, sprite->h);
|
||||
image_clear(image, 0);
|
||||
sprite_render(sprite, image, 0, 0);
|
||||
sprite_free(sprite);
|
||||
|
||||
/* calculate the thumbnail size */
|
||||
thumb_w = MAX_THUMBNAIL_SIZE * image->w / MAX(image->w, image->h);
|
||||
thumb_h = MAX_THUMBNAIL_SIZE * image->h / MAX(image->w, image->h);
|
||||
if (MAX(thumb_w, thumb_h) > MAX(image->w, image->h)) {
|
||||
thumb_w = image->w;
|
||||
thumb_h = image->h;
|
||||
}
|
||||
thumb_w = MID(1, thumb_w, MAX_THUMBNAIL_SIZE);
|
||||
thumb_h = MID(1, thumb_h, MAX_THUMBNAIL_SIZE);
|
||||
|
||||
/* stretch the 'image' */
|
||||
data->thumbnail = image_new(image->imgtype, thumb_w, thumb_h);
|
||||
image_clear(data->thumbnail, 0);
|
||||
image_scale(data->thumbnail, image, 0, 0, thumb_w, thumb_h);
|
||||
image_free(image);
|
||||
}
|
||||
}
|
||||
|
||||
fop_done(fop);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the gui-monitor (a timer in the gui module that is called
|
||||
* every 100 milliseconds).
|
||||
*
|
||||
* [main thread]
|
||||
*/
|
||||
static void monitor_thumbnail_generation(void *_data)
|
||||
{
|
||||
ThumbnailData *data = (ThumbnailData *)_data;
|
||||
FileOp *fop = (FileOp *)data->fop;
|
||||
|
||||
/* is done? ...ok, now the thumbnail is in the main thread only... */
|
||||
if (fop_is_done(fop)) {
|
||||
/* set the thumbnail of the file-item */
|
||||
if (data->thumbnail) {
|
||||
BITMAP *bmp = create_bitmap(data->thumbnail->w,
|
||||
data->thumbnail->h);
|
||||
|
||||
select_palette(data->pal);
|
||||
image_to_allegro(data->thumbnail, bmp, 0, 0);
|
||||
unselect_palette();
|
||||
|
||||
image_free(data->thumbnail);
|
||||
|
||||
fileitem_set_thumbnail(data->fileitem, bmp);
|
||||
|
||||
/* is the selected file-item the one that now has a thumbnail? */
|
||||
if (fileview_get_selected(data->fileview) == data->fileitem) {
|
||||
/* we have to dirty the file-view to show the thumbnail */
|
||||
jwidget_dirty(data->fileview);
|
||||
}
|
||||
}
|
||||
|
||||
remove_gui_monitor(data->monitor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [main thread]
|
||||
*/
|
||||
static void monitor_free_thumbnail_generation(void *_data)
|
||||
{
|
||||
ThumbnailData *data = (ThumbnailData *)_data;
|
||||
FileOp *fop = (FileOp *)data->fop;
|
||||
|
||||
fop_stop(fop);
|
||||
jthread_join(data->thread);
|
||||
|
||||
jlist_remove(fileview_data(data->fileview)->monitors,
|
||||
data->monitor);
|
||||
|
||||
fop_free(fop);
|
||||
jfree(data);
|
||||
}
|
||||
|
@ -36,5 +36,6 @@ FileItem *fileview_get_selected(JWidget fileview);
|
||||
void fileview_set_current_folder(JWidget widget, FileItem *folder);
|
||||
|
||||
void fileview_goup(JWidget fileview);
|
||||
void fileview_stop_threads(JWidget fileview);
|
||||
|
||||
#endif /* WIDGETS_FILEVIEW_H */
|
||||
|
Loading…
x
Reference in New Issue
Block a user