mirror of https://github.com/aseprite/aseprite.git
				
				
				
			Added progress bar to apply-effect and save file operations.
Added support to configure file format with a FileData like JpegData.
This commit is contained in:
		
							parent
							
								
									0ffbf5164c
								
							
						
					
					
						commit
						a951368da6
					
				
							
								
								
									
										28
									
								
								ChangeLog
								
								
								
								
							
							
						
						
									
										28
									
								
								ChangeLog
								
								
								
								
							|  | @ -1,3 +1,31 @@ | ||||||
|  | 2008-03-29  David A. Capello  <dacap@users.sourceforge.net> | ||||||
|  | 
 | ||||||
|  | 	* src/file/jpeg_format.c (getdata_JPEG): Added from configure_jpeg. | ||||||
|  | 
 | ||||||
|  | 	* src/file/filedata.h (JpegData): Added. | ||||||
|  | 
 | ||||||
|  | 	* src/file/file.h (FileFormat): Added the `getdata' method to | ||||||
|  | 	configure the output format. | ||||||
|  | 
 | ||||||
|  | 2008-03-28  David A. Capello  <dacap@users.sourceforge.net> | ||||||
|  | 
 | ||||||
|  | 	* src/commands/cmd_save_file.c (save_sprite_in_background): Added | ||||||
|  | 	to save sprites with progress bar. | ||||||
|  | 
 | ||||||
|  | 	* src/commands/fx/effectbg.c (effect_apply_to_target_with_progressbar): | ||||||
|  | 	Added to show progress bar and background processing when the user | ||||||
|  | 	applies an effect. | ||||||
|  | 
 | ||||||
|  | 	* src/effect/effect.h (Effect): Added progress information to | ||||||
|  | 	customize the progress and cancellation of the effect operations. | ||||||
|  | 
 | ||||||
|  | 	* src/file/fli_format.c (load_FLI), | ||||||
|  | 	  src/file/gif_format.c (load_GIF): Now these two routines | ||||||
|  | 	  configure the only layer as `Background'. | ||||||
|  | 
 | ||||||
|  | 	* src/file/file.h (FileOp): Added seq.has_alpha so a PNG file with | ||||||
|  | 	alpha hasn't a `Background' layer. | ||||||
|  | 
 | ||||||
| 2008-03-27  David A. Capello  <dacap@users.sourceforge.net> | 2008-03-27  David A. Capello  <dacap@users.sourceforge.net> | ||||||
| 
 | 
 | ||||||
| 	* Added a call to undo_set_label(...) for every undo operation in | 	* Added a call to undo_set_label(...) for every undo operation in | ||||||
|  |  | ||||||
							
								
								
									
										1
									
								
								TODO.txt
								
								
								
								
							
							
						
						
									
										1
									
								
								TODO.txt
								
								
								
								
							|  | @ -8,6 +8,7 @@ Next beta | ||||||
|   + quick_move |   + quick_move | ||||||
|   + quick_copy |   + quick_copy | ||||||
|   + quick_swap |   + quick_swap | ||||||
|  | - search for "TODO remove me" | ||||||
| - add the progress bar for effects and save-file. | - add the progress bar for effects and save-file. | ||||||
| - fix colors | - fix colors | ||||||
| - tooltips for color-bar. | - tooltips for color-bar. | ||||||
|  |  | ||||||
|  | @ -204,7 +204,7 @@ | ||||||
| 	<menu name="&Tools"> | 	<menu name="&Tools"> | ||||||
| 	    <item command="configure_tools" name="&Configure" /> | 	    <item command="configure_tools" name="&Configure" /> | ||||||
| 	    <separator /> | 	    <separator /> | ||||||
| 	    <item command="film_editor" name="&Film Editor" /> | 	    <item command="animation_editor" name="&Animation Editor" /> | ||||||
| 	    <item command="palette_editor" name="&Palette Editor" /> | 	    <item command="palette_editor" name="&Palette Editor" /> | ||||||
| 	    <separator /> | 	    <separator /> | ||||||
| 	    <menu name="F&X" id="fx_popup"> | 	    <menu name="F&X" id="fx_popup"> | ||||||
|  |  | ||||||
|  | @ -62,7 +62,6 @@ COMMON_SOURCES =					\ | ||||||
| 	src/commands/cmd_reselect_mask.c		\ | 	src/commands/cmd_reselect_mask.c		\ | ||||||
| 	src/commands/cmd_run_script.c			\ | 	src/commands/cmd_run_script.c			\ | ||||||
| 	src/commands/cmd_save_file.c			\ | 	src/commands/cmd_save_file.c			\ | ||||||
| 	src/commands/cmd_save_file_as.c			\ |  | ||||||
| 	src/commands/cmd_save_mask.c			\ | 	src/commands/cmd_save_mask.c			\ | ||||||
| 	src/commands/cmd_screen_shot.c			\ | 	src/commands/cmd_screen_shot.c			\ | ||||||
| 	src/commands/cmd_select_file.c			\ | 	src/commands/cmd_select_file.c			\ | ||||||
|  | @ -77,6 +76,7 @@ COMMON_SOURCES =					\ | ||||||
| 	src/commands/fx/cmd_despeckle.c			\ | 	src/commands/fx/cmd_despeckle.c			\ | ||||||
| 	src/commands/fx/cmd_invert_color.c		\ | 	src/commands/fx/cmd_invert_color.c		\ | ||||||
| 	src/commands/fx/cmd_replace_color.c		\ | 	src/commands/fx/cmd_replace_color.c		\ | ||||||
|  | 	src/commands/fx/effectbg.c			\ | ||||||
| 	src/console/console.c				\ | 	src/console/console.c				\ | ||||||
| 	src/core/app.c					\ | 	src/core/app.c					\ | ||||||
| 	src/core/cfg.c					\ | 	src/core/cfg.c					\ | ||||||
|  |  | ||||||
|  | @ -177,7 +177,7 @@ static void cmd_open_file_execute(const char *argument) | ||||||
| 	} | 	} | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     /* else do nothing (the user canceled or something like that) */ |     /* else do nothing (the user cancelled or something like that) */ | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -20,40 +20,153 @@ | ||||||
| 
 | 
 | ||||||
| #include <allegro.h> | #include <allegro.h> | ||||||
| 
 | 
 | ||||||
| #include "jinete/jbase.h" | #include "jinete/jinete.h" | ||||||
| 
 | 
 | ||||||
| #include "commands/commands.h" | #include "commands/commands.h" | ||||||
| #include "core/app.h" | #include "core/app.h" | ||||||
| #include "console/console.h" | #include "console/console.h" | ||||||
|  | #include "dialogs/filesel.h" | ||||||
| #include "file/file.h" | #include "file/file.h" | ||||||
|  | #include "modules/gui.h" | ||||||
| #include "modules/recent.h" | #include "modules/recent.h" | ||||||
| #include "modules/sprites.h" | #include "modules/sprites.h" | ||||||
| #include "raster/sprite.h" | #include "raster/sprite.h" | ||||||
| #include "widgets/statebar.h" | #include "widgets/statebar.h" | ||||||
| 
 | 
 | ||||||
|  | typedef struct SaveFileData | ||||||
|  | { | ||||||
|  |   Monitor *monitor; | ||||||
|  |   FileOp *fop; | ||||||
|  |   Progress *progress; | ||||||
|  |   JThread thread; | ||||||
|  |   JWidget alert_window; | ||||||
|  | } SaveFileData; | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Thread to do the hard work: save the file to the disk. | ||||||
|  |  * | ||||||
|  |  * [saving thread] | ||||||
|  |  */ | ||||||
|  | static void savefile_bg(void *fop_data) | ||||||
|  | { | ||||||
|  |   FileOp *fop = (FileOp *)fop_data; | ||||||
|  |   fop_operate(fop); | ||||||
|  |   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_savefile_bg(void *_data) | ||||||
|  | { | ||||||
|  |   SaveFileData *data = (SaveFileData *)_data; | ||||||
|  |   FileOp *fop = (FileOp *)data->fop; | ||||||
|  | 
 | ||||||
|  |   if (data->progress) | ||||||
|  |     progress_update(data->progress, fop_get_progress(fop)); | ||||||
|  | 
 | ||||||
|  |   if (fop_is_done(fop)) | ||||||
|  |     remove_gui_monitor(data->monitor); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Called when the monitor is destroyed. | ||||||
|  |  *  | ||||||
|  |  * [main thread] | ||||||
|  |  */ | ||||||
|  | static void monitor_free(void *_data) | ||||||
|  | { | ||||||
|  |   SaveFileData *data = (SaveFileData *)_data; | ||||||
|  | 
 | ||||||
|  |   if (data->alert_window != NULL) { | ||||||
|  |     data->monitor = NULL; | ||||||
|  |     jwindow_close(data->alert_window, NULL); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void save_sprite_in_background(Sprite *sprite) | ||||||
|  | { | ||||||
|  |   FileOp *fop = fop_to_save_sprite(sprite); | ||||||
|  |   if (fop) { | ||||||
|  |     JThread thread = jthread_new(savefile_bg, fop); | ||||||
|  |     if (thread) { | ||||||
|  |       SaveFileData *data = jnew(SaveFileData, 1); | ||||||
|  | 
 | ||||||
|  |       data->fop = fop; | ||||||
|  |       data->progress = progress_new(app_get_statusbar()); | ||||||
|  |       data->thread = thread; | ||||||
|  |       data->alert_window = jalert_new(PACKAGE | ||||||
|  | 				      "<<Saving file:<<%s||&Cancel", | ||||||
|  | 				      get_filename(sprite->filename)); | ||||||
|  |       data->monitor = NULL; | ||||||
|  | 
 | ||||||
|  |       /* add a monitor to check the saving (FileOp) progress */ | ||||||
|  |       data->monitor = add_gui_monitor(monitor_savefile_bg, | ||||||
|  | 				      monitor_free, data); | ||||||
|  | 
 | ||||||
|  |       /* TODO error handling */ | ||||||
|  | 
 | ||||||
|  |       jwindow_open_fg(data->alert_window); | ||||||
|  | 
 | ||||||
|  |       if (data->monitor != NULL) | ||||||
|  | 	remove_gui_monitor(data->monitor); | ||||||
|  | 
 | ||||||
|  |       /* wait the `savefile_bg' thread */ | ||||||
|  |       jthread_join(data->thread); | ||||||
|  | 
 | ||||||
|  |       /* show any error */ | ||||||
|  |       if (fop->error) { | ||||||
|  | 	console_open(); | ||||||
|  | 	console_printf(fop->error); | ||||||
|  | 	console_close(); | ||||||
|  |       } | ||||||
|  |       /* no error? */ | ||||||
|  |       else { | ||||||
|  | 	recent_file(sprite->filename); | ||||||
|  | 	sprite_mark_as_saved(sprite); | ||||||
|  | 	statusbar_set_text(app_get_statusbar(), | ||||||
|  | 			   2000, "File %s, saved.", | ||||||
|  | 			   get_filename(sprite->filename)); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       progress_free(data->progress); | ||||||
|  |       jwidget_free(data->alert_window); | ||||||
|  |       fop_free(fop); | ||||||
|  |       jfree(data); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  Save File | ||||||
|  |  *********************************************************************/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Returns true if there is a current sprite to save. | ||||||
|  |  * | ||||||
|  |  * [main thread] | ||||||
|  |  */ | ||||||
| static bool cmd_save_file_enabled(const char *argument) | static bool cmd_save_file_enabled(const char *argument) | ||||||
| { | { | ||||||
|   return current_sprite != NULL; |   return current_sprite != NULL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * Saves the current sprite in a file. | ||||||
|  |  *  | ||||||
|  |  * [main thread] | ||||||
|  |  */ | ||||||
| static void cmd_save_file_execute(const char *argument) | static void cmd_save_file_execute(const char *argument) | ||||||
| { | { | ||||||
|  |   Sprite *sprite = current_sprite; | ||||||
|  | 
 | ||||||
|   /* if the sprite is associated to a file in the file-system, we can
 |   /* if the sprite is associated to a file in the file-system, we can
 | ||||||
|      save it directly without user interaction */ |      save it directly without user interaction */ | ||||||
|   if (sprite_is_associated_to_file(current_sprite)) { |   if (sprite_is_associated_to_file(sprite)) { | ||||||
|     if (sprite_save(current_sprite) == 0) { |     save_sprite_in_background(sprite); | ||||||
|       recent_file(current_sprite->filename); |  | ||||||
|       sprite_mark_as_saved(current_sprite); |  | ||||||
| 
 |  | ||||||
|       if (app_get_statusbar()) |  | ||||||
| 	statusbar_set_text(app_get_statusbar(), |  | ||||||
| 			   1000, "File %s, saved.", |  | ||||||
| 			   get_filename(current_sprite->filename)); |  | ||||||
|     } |  | ||||||
|     else { |  | ||||||
|       /* TODO if the user cancel we shouldn't unrecent the file */ |  | ||||||
|       unrecent_file(current_sprite->filename); |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
|   /* if the sprite isn't associated to a file, we must to show the
 |   /* if the sprite isn't associated to a file, we must to show the
 | ||||||
|      save-as dialog to the user to select for first time the file-name |      save-as dialog to the user to select for first time the file-name | ||||||
|  | @ -63,6 +176,64 @@ static void cmd_save_file_execute(const char *argument) | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  Save File As | ||||||
|  |  *********************************************************************/ | ||||||
|  | 
 | ||||||
|  | static bool cmd_save_file_as_enabled(const char *argument) | ||||||
|  | { | ||||||
|  |   return current_sprite != NULL; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void cmd_save_file_as_execute(const char *argument) | ||||||
|  | { | ||||||
|  |   Sprite *sprite = current_sprite; | ||||||
|  |   char filename[4096]; | ||||||
|  |   char exts[4096]; | ||||||
|  |   char *newfilename; | ||||||
|  |   int ret; | ||||||
|  | 
 | ||||||
|  |   ustrcpy(filename, sprite->filename); | ||||||
|  |   get_writable_extensions(exts, sizeof(exts)); | ||||||
|  | 
 | ||||||
|  |   for (;;) { | ||||||
|  |     newfilename = ase_file_selector(_("Save Sprite"), filename, exts); | ||||||
|  |     if (!newfilename) | ||||||
|  |       return; | ||||||
|  |     ustrcpy(filename, newfilename); | ||||||
|  |     jfree(newfilename); | ||||||
|  | 
 | ||||||
|  |     /* does the file exist? */ | ||||||
|  |     if (exists(filename)) { | ||||||
|  |       /* ask if the user wants overwrite the file? */ | ||||||
|  |       ret = jalert("%s<<%s<<%s||%s||%s||%s", | ||||||
|  | 		   _("Warning"), | ||||||
|  | 		   _("File exists, overwrite it?"), | ||||||
|  | 		   get_filename(filename), | ||||||
|  | 		   _("&Yes"), _("&No"), _("&Cancel")); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |       break; | ||||||
|  | 
 | ||||||
|  |     /* "yes": we must continue with the operation... */ | ||||||
|  |     if (ret == 1) | ||||||
|  |       break; | ||||||
|  |     /* "cancel" or <esc> per example: we back doing nothing */ | ||||||
|  |     else if (ret != 2) | ||||||
|  |       return; | ||||||
|  | 
 | ||||||
|  |     /* "no": we must back to select other file-name */ | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   sprite_set_filename(sprite, filename); | ||||||
|  |   app_realloc_sprite_list(); | ||||||
|  | 
 | ||||||
|  |   save_sprite_in_background(sprite); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Command to save the current sprite in its associated file. | ||||||
|  |  */ | ||||||
| Command cmd_save_file = { | Command cmd_save_file = { | ||||||
|   CMD_SAVE_FILE, |   CMD_SAVE_FILE, | ||||||
|   cmd_save_file_enabled, |   cmd_save_file_enabled, | ||||||
|  | @ -70,3 +241,14 @@ Command cmd_save_file = { | ||||||
|   cmd_save_file_execute, |   cmd_save_file_execute, | ||||||
|   NULL |   NULL | ||||||
| }; | }; | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Command to save the current sprite in another file. | ||||||
|  |  */ | ||||||
|  | Command cmd_save_file_as = { | ||||||
|  |   CMD_SAVE_FILE_AS, | ||||||
|  |   cmd_save_file_as_enabled, | ||||||
|  |   NULL, | ||||||
|  |   cmd_save_file_as_execute, | ||||||
|  |   NULL | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | @ -1,98 +0,0 @@ | ||||||
| /* 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 "config.h" |  | ||||||
| 
 |  | ||||||
| #include <allegro.h> |  | ||||||
| 
 |  | ||||||
| #include "jinete/jalert.h" |  | ||||||
| 
 |  | ||||||
| #include "commands/commands.h" |  | ||||||
| #include "console/console.h" |  | ||||||
| #include "core/app.h" |  | ||||||
| #include "dialogs/filesel.h" |  | ||||||
| #include "file/file.h" |  | ||||||
| #include "modules/recent.h" |  | ||||||
| #include "modules/gui.h" |  | ||||||
| #include "modules/sprites.h" |  | ||||||
| #include "raster/sprite.h" |  | ||||||
| 
 |  | ||||||
| static bool cmd_save_file_as_enabled(const char *argument) |  | ||||||
| { |  | ||||||
|   return current_sprite != NULL; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void cmd_save_file_as_execute(const char *argument) |  | ||||||
| { |  | ||||||
|   char filename[4096]; |  | ||||||
|   char exts[4096]; |  | ||||||
|   char *newfilename; |  | ||||||
|   int ret; |  | ||||||
| 
 |  | ||||||
|   ustrcpy(filename, current_sprite->filename); |  | ||||||
|   get_writable_extensions(exts, sizeof(exts)); |  | ||||||
| 
 |  | ||||||
|   for (;;) { |  | ||||||
|     newfilename = ase_file_selector(_("Save Sprite"), filename, exts); |  | ||||||
|     if (!newfilename) |  | ||||||
|       return; |  | ||||||
|     ustrcpy(filename, newfilename); |  | ||||||
|     jfree(newfilename); |  | ||||||
| 
 |  | ||||||
|     /* does the file exist? */ |  | ||||||
|     if (exists(filename)) { |  | ||||||
|       /* ask if the user wants overwrite the file? */ |  | ||||||
|       ret = jalert("%s<<%s<<%s||%s||%s||%s", |  | ||||||
| 		   _("Warning"), |  | ||||||
| 		   _("File exists, overwrite it?"), |  | ||||||
| 		   get_filename(filename), |  | ||||||
| 		   _("&Yes"), _("&No"), _("&Cancel")); |  | ||||||
|     } |  | ||||||
|     else |  | ||||||
|       break; |  | ||||||
| 
 |  | ||||||
|     /* "yes": we must continue with the operation... */ |  | ||||||
|     if (ret == 1) |  | ||||||
|       break; |  | ||||||
|     /* "cancel" or <esc> per example: we back doing nothing */ |  | ||||||
|     else if (ret != 2) |  | ||||||
|       return; |  | ||||||
| 
 |  | ||||||
|     /* "no": we must back to select other file-name */ |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   sprite_set_filename(current_sprite, filename); |  | ||||||
|   app_realloc_sprite_list(); |  | ||||||
| 
 |  | ||||||
|   if (sprite_save(current_sprite) == 0) { |  | ||||||
|     recent_file(filename); |  | ||||||
|     sprite_mark_as_saved(current_sprite); |  | ||||||
|   } |  | ||||||
|   else { |  | ||||||
|     /* TODO if the user cancel we shouldn't unrecent the file */ |  | ||||||
|     unrecent_file(filename); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| Command cmd_save_file_as = { |  | ||||||
|   CMD_SAVE_FILE_AS, |  | ||||||
|   cmd_save_file_as_enabled, |  | ||||||
|   NULL, |  | ||||||
|   cmd_save_file_as_execute, |  | ||||||
|   NULL |  | ||||||
| }; |  | ||||||
|  | @ -21,6 +21,7 @@ | ||||||
| #include "jinete/jinete.h" | #include "jinete/jinete.h" | ||||||
| 
 | 
 | ||||||
| #include "commands/commands.h" | #include "commands/commands.h" | ||||||
|  | #include "commands/fx/effectbg.h" | ||||||
| #include "console/console.h" | #include "console/console.h" | ||||||
| #include "core/app.h" | #include "core/app.h" | ||||||
| #include "core/cfg.h" | #include "core/cfg.h" | ||||||
|  | @ -124,7 +125,7 @@ static void cmd_color_curve_execute(const char *argument) | ||||||
|   jwindow_open_fg(window); |   jwindow_open_fg(window); | ||||||
| 
 | 
 | ||||||
|   if (jwindow_get_killer(window) == button_ok) { |   if (jwindow_get_killer(window) == button_ok) { | ||||||
|     effect_apply_to_target(effect); |     effect_apply_to_target_with_progressbar(effect); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   effect_free(effect); |   effect_free(effect); | ||||||
|  |  | ||||||
|  | @ -32,6 +32,7 @@ | ||||||
| #include "jinete/jwindow.h" | #include "jinete/jwindow.h" | ||||||
| 
 | 
 | ||||||
| #include "commands/commands.h" | #include "commands/commands.h" | ||||||
|  | #include "commands/fx/effectbg.h" | ||||||
| #include "console/console.h" | #include "console/console.h" | ||||||
| #include "core/cfg.h" | #include "core/cfg.h" | ||||||
| #include "core/color.h" | #include "core/color.h" | ||||||
|  | @ -149,7 +150,7 @@ static void cmd_convolution_matrix_execute(const char *argument) | ||||||
|   jwindow_open_fg(window); |   jwindow_open_fg(window); | ||||||
| 
 | 
 | ||||||
|   if (jwindow_get_killer(window) == button_ok) { |   if (jwindow_get_killer(window) == button_ok) { | ||||||
|     effect_apply_to_target(effect); |     effect_apply_to_target_with_progressbar(effect); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   effect_free(effect); |   effect_free(effect); | ||||||
|  |  | ||||||
|  | @ -28,6 +28,7 @@ | ||||||
| #include "jinete/jwindow.h" | #include "jinete/jwindow.h" | ||||||
| 
 | 
 | ||||||
| #include "commands/commands.h" | #include "commands/commands.h" | ||||||
|  | #include "commands/fx/effectbg.h" | ||||||
| #include "console/console.h" | #include "console/console.h" | ||||||
| #include "core/cfg.h" | #include "core/cfg.h" | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
|  | @ -130,7 +131,7 @@ static void cmd_despeckle_execute(const char *argument) | ||||||
|   jwindow_open_fg(window); |   jwindow_open_fg(window); | ||||||
| 
 | 
 | ||||||
|   if (jwindow_get_killer(window) == button_ok) { |   if (jwindow_get_killer(window) == button_ok) { | ||||||
|     effect_apply_to_target(effect); |     effect_apply_to_target_with_progressbar(effect); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   effect_free(effect); |   effect_free(effect); | ||||||
|  |  | ||||||
|  | @ -27,6 +27,7 @@ | ||||||
| #include "jinete/jwindow.h" | #include "jinete/jwindow.h" | ||||||
| 
 | 
 | ||||||
| #include "commands/commands.h" | #include "commands/commands.h" | ||||||
|  | #include "commands/fx/effectbg.h" | ||||||
| #include "console/console.h" | #include "console/console.h" | ||||||
| #include "core/cfg.h" | #include "core/cfg.h" | ||||||
| #include "core/color.h" | #include "core/color.h" | ||||||
|  | @ -109,7 +110,7 @@ static void cmd_invert_color_execute(const char *argument) | ||||||
|   jwindow_open_fg(window); |   jwindow_open_fg(window); | ||||||
| 
 | 
 | ||||||
|   if (jwindow_get_killer(window) == button_ok) { |   if (jwindow_get_killer(window) == button_ok) { | ||||||
|     effect_apply_to_target(effect); |     effect_apply_to_target_with_progressbar(effect); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   effect_free(effect); |   effect_free(effect); | ||||||
|  |  | ||||||
|  | @ -23,6 +23,7 @@ | ||||||
| #include "jinete/jinete.h" | #include "jinete/jinete.h" | ||||||
| 
 | 
 | ||||||
| #include "commands/commands.h" | #include "commands/commands.h" | ||||||
|  | #include "commands/fx/effectbg.h" | ||||||
| #include "console/console.h" | #include "console/console.h" | ||||||
| #include "core/app.h" | #include "core/app.h" | ||||||
| #include "core/cfg.h" | #include "core/cfg.h" | ||||||
|  | @ -137,7 +138,7 @@ static void cmd_replace_color_execute(const char *argument) | ||||||
|   jwindow_open_fg(window); |   jwindow_open_fg(window); | ||||||
| 
 | 
 | ||||||
|   if (jwindow_get_killer(window) == button_ok) { |   if (jwindow_get_killer(window) == button_ok) { | ||||||
|     effect_apply_to_target(effect); |     effect_apply_to_target_with_progressbar(effect); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   effect_free(effect); |   effect_free(effect); | ||||||
|  |  | ||||||
|  | @ -0,0 +1,193 @@ | ||||||
|  | /* 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 "config.h" | ||||||
|  | 
 | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  | 
 | ||||||
|  | #include "jinete/jinete.h" | ||||||
|  | 
 | ||||||
|  | #include "core/app.h" | ||||||
|  | #include "core/cfg.h" | ||||||
|  | #include "effect/effect.h" | ||||||
|  | #include "modules/editors.h" | ||||||
|  | #include "modules/gui.h" | ||||||
|  | #include "modules/sprites.h" | ||||||
|  | #include "raster/sprite.h" | ||||||
|  | #include "widgets/editor.h" | ||||||
|  | #include "widgets/statebar.h" | ||||||
|  | 
 | ||||||
|  | /**********************************************************************
 | ||||||
|  |  Apply effect in two threads: bg-thread to modify the sprite, and the | ||||||
|  |  main thread to monitoring the progress. | ||||||
|  |  **********************************************************************/ | ||||||
|  | 
 | ||||||
|  | typedef struct ThreadData | ||||||
|  | { | ||||||
|  |   Effect *effect;		/* effect to be applied */ | ||||||
|  |   JMutex mutex;			/* mutex to access to 'pos', 'done'
 | ||||||
|  | 				   and 'cancelled' fields in different | ||||||
|  | 				   threads */ | ||||||
|  |   float pos;			/* current progress position */ | ||||||
|  |   bool done;			/* was the effect completelly applied? */ | ||||||
|  |   bool cancelled;		/* was the effect cancelled by the user?  */ | ||||||
|  |   Monitor *monitor;		/* monitor to update the progress-bar */ | ||||||
|  |   Progress *progress;		/* the progress-bar */ | ||||||
|  |   JThread thread;		/* thread to apply the effect in background */ | ||||||
|  |   JWidget alert_window;		/* alert for the user to cancel the
 | ||||||
|  | 				   effect-progress if he wants */ | ||||||
|  | } ThreadData; | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Called by @ref effect_apply to informate the progress of the | ||||||
|  |  * effect. | ||||||
|  |  *  | ||||||
|  |  * [effect thread] | ||||||
|  |  */ | ||||||
|  | static void effect_progress_hook(void *_data, float progress) | ||||||
|  | { | ||||||
|  |   ThreadData *data = (ThreadData *)_data; | ||||||
|  | 
 | ||||||
|  |   jmutex_lock(data->mutex); | ||||||
|  |   data->pos = progress; | ||||||
|  |   jmutex_unlock(data->mutex); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Called by @ref effect_apply to know if the user cancelled the | ||||||
|  |  * operation. | ||||||
|  |  *  | ||||||
|  |  * [effect thread] | ||||||
|  |  */ | ||||||
|  | static bool effect_is_cancelled_hook(void *_data) | ||||||
|  | { | ||||||
|  |   ThreadData *data = (ThreadData *)_data; | ||||||
|  |   bool cancelled; | ||||||
|  | 
 | ||||||
|  |   jmutex_lock(data->mutex); | ||||||
|  |   cancelled = data->cancelled; | ||||||
|  |   jmutex_unlock(data->mutex); | ||||||
|  | 
 | ||||||
|  |   return cancelled; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Applies the effect to the sprite in a background thread. | ||||||
|  |  *  | ||||||
|  |  * [effect thread] | ||||||
|  |  */ | ||||||
|  | static void effect_bg(void *_data) | ||||||
|  | { | ||||||
|  |   ThreadData *data = (ThreadData *)_data; | ||||||
|  | 
 | ||||||
|  |   /* apply the effect */ | ||||||
|  |   effect_apply_to_target(data->effect); | ||||||
|  | 
 | ||||||
|  |   /* mark the work as 'done' */ | ||||||
|  |   jmutex_lock(data->mutex); | ||||||
|  |   data->done = TRUE; | ||||||
|  |   jmutex_unlock(data->mutex); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Called by the gui-monitor (a timer in the gui module that is called | ||||||
|  |  * every 100 milliseconds). | ||||||
|  |  *  | ||||||
|  |  * [main thread] | ||||||
|  |  */ | ||||||
|  | static void monitor_effect_bg(void *_data) | ||||||
|  | { | ||||||
|  |   ThreadData *data = (ThreadData *)_data; | ||||||
|  |   float pos; | ||||||
|  |   bool done; | ||||||
|  | 
 | ||||||
|  |   jmutex_lock(data->mutex); | ||||||
|  |   pos = data->pos; | ||||||
|  |   done = data->done; | ||||||
|  |   jmutex_unlock(data->mutex); | ||||||
|  | 
 | ||||||
|  |   if (data->progress) | ||||||
|  |     progress_update(data->progress, pos); | ||||||
|  | 
 | ||||||
|  |   if (data->done) | ||||||
|  |     remove_gui_monitor(data->monitor); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Called to destroy the data of the monitor. | ||||||
|  |  *  | ||||||
|  |  * [main thread] | ||||||
|  |  */ | ||||||
|  | static void monitor_free(void *_data) | ||||||
|  | { | ||||||
|  |   ThreadData *data = (ThreadData *)_data; | ||||||
|  | 
 | ||||||
|  |   if (data->alert_window != NULL) | ||||||
|  |     jwindow_close(data->alert_window, NULL); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Applies the effect to the specified targets in the effect structure. | ||||||
|  |  *  | ||||||
|  |  * [main thread] | ||||||
|  |  */ | ||||||
|  | void effect_apply_to_target_with_progressbar(Effect *effect) | ||||||
|  | { | ||||||
|  |   ThreadData *data; | ||||||
|  | 
 | ||||||
|  |   data = jnew(ThreadData, 1); | ||||||
|  |   if (data == NULL) { | ||||||
|  |     jalert("Error<<Not enough memory||&OK"); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   effect->progress_data = data; | ||||||
|  |   effect->progress = effect_progress_hook; | ||||||
|  |   effect->is_cancelled = effect_is_cancelled_hook; | ||||||
|  | 
 | ||||||
|  |   data->mutex = jmutex_new(); | ||||||
|  |   data->effect = effect; | ||||||
|  |   data->pos = 0.0; | ||||||
|  |   data->done = FALSE; | ||||||
|  |   data->cancelled = FALSE; | ||||||
|  |   data->progress = progress_new(app_get_statusbar()); | ||||||
|  |   data->thread = jthread_new(effect_bg, data); | ||||||
|  |   data->alert_window = jalert_new(PACKAGE | ||||||
|  | 				  "<<Applying effect...||&Cancel"); | ||||||
|  |   data->monitor = add_gui_monitor(monitor_effect_bg, | ||||||
|  | 				  monitor_free, data); | ||||||
|  | 
 | ||||||
|  |   /* TODO error handling */ | ||||||
|  | 
 | ||||||
|  |   jwindow_open_fg(data->alert_window); | ||||||
|  | 
 | ||||||
|  |   jmutex_lock(data->mutex); | ||||||
|  |   if (!data->done) { | ||||||
|  |     remove_gui_monitor(data->monitor); | ||||||
|  |     data->cancelled = TRUE; | ||||||
|  |   } | ||||||
|  |   jmutex_unlock(data->mutex); | ||||||
|  | 
 | ||||||
|  |   /* wait the `effect_bg' thread */ | ||||||
|  |   jthread_join(data->thread); | ||||||
|  | 
 | ||||||
|  |   progress_free(data->progress); | ||||||
|  |   jwidget_free(data->alert_window); | ||||||
|  |   jfree(data); | ||||||
|  | } | ||||||
|  | @ -0,0 +1,26 @@ | ||||||
|  | /* 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 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef COMMANDS_FX_EFFECTBG_H | ||||||
|  | #define COMMANDS_FX_EFFECTBG_H | ||||||
|  | 
 | ||||||
|  | struct Effect; | ||||||
|  | 
 | ||||||
|  | void effect_apply_to_target_with_progressbar(struct Effect *effect); | ||||||
|  | 
 | ||||||
|  | #endif /* COMMANDS_FX_EFFECTBG_H */ | ||||||
|  | @ -465,7 +465,7 @@ void app_realloc_sprite_list(void) | ||||||
|  * |  * | ||||||
|  * @warning This routine can't be used when a menu callback was |  * @warning This routine can't be used when a menu callback was | ||||||
|  * called, because, it destroy the menus, you should use |  * called, because, it destroy the menus, you should use | ||||||
|  * rebuild_recent_list() instead (src/gui/gui.c). |  * schedule_rebuild_recent_list() instead (src/modules/gui.c). | ||||||
|  */ |  */ | ||||||
| bool app_realloc_recent_list(void) | bool app_realloc_recent_list(void) | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -701,8 +701,9 @@ void color_to_formalstring(int imgtype, color_t color, | ||||||
| 	break; | 	break; | ||||||
| 
 | 
 | ||||||
|       case COLOR_TYPE_INDEX: { |       case COLOR_TYPE_INDEX: { | ||||||
| 	ase_uint32 _c = palette_get_entry(get_current_palette(), data & 0xff); | 	ase_uint32 _c; | ||||||
| 	data = GET_COLOR_DATA_INDEX(color); | 	data = GET_COLOR_DATA_INDEX(color); | ||||||
|  | 	_c = palette_get_entry(get_current_palette(), data & 0xff); | ||||||
| 	uszprintf(buf, size, "%s %d (RGB %d %d %d)", | 	uszprintf(buf, size, "%s %d (RGB %d %d %d)", | ||||||
| 		  _("Index"), | 		  _("Index"), | ||||||
| 		  data & 0xff, | 		  data & 0xff, | ||||||
|  |  | ||||||
|  | @ -982,7 +982,7 @@ static FileItem *get_fileitem_by_path(const char *path, bool create_if_not) | ||||||
|   FileItem *fileitem; |   FileItem *fileitem; | ||||||
|   int attrib; |   int attrib; | ||||||
| 
 | 
 | ||||||
|  #ifdef ALLEGRO_UNIX | #ifdef ALLEGRO_UNIX | ||||||
|   if (*path == 0) |   if (*path == 0) | ||||||
|     return rootitem; |     return rootitem; | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -50,8 +50,8 @@ void curve_get_values(Curve *curve, int x1, int x2, int *values); | ||||||
| 
 | 
 | ||||||
| void set_color_curve(Curve *curve); | void set_color_curve(Curve *curve); | ||||||
| 
 | 
 | ||||||
| void apply_color_curve4 (struct Effect *effect); | void apply_color_curve4(struct Effect *effect); | ||||||
| void apply_color_curve2 (struct Effect *effect); | void apply_color_curve2(struct Effect *effect); | ||||||
| void apply_color_curve1 (struct Effect *effect); | void apply_color_curve1(struct Effect *effect); | ||||||
| 
 | 
 | ||||||
| #endif /* EFFECT_COLCURVE_H */ | #endif /* EFFECT_COLCURVE_H */ | ||||||
|  |  | ||||||
|  | @ -55,8 +55,8 @@ JList get_convmatr_stock(void); | ||||||
| void init_convolution_matrix(void); | void init_convolution_matrix(void); | ||||||
| void exit_convolution_matrix(void); | void exit_convolution_matrix(void); | ||||||
| 
 | 
 | ||||||
| void apply_convolution_matrix4 (struct Effect *effect); | void apply_convolution_matrix4(struct Effect *effect); | ||||||
| void apply_convolution_matrix2 (struct Effect *effect); | void apply_convolution_matrix2(struct Effect *effect); | ||||||
| void apply_convolution_matrix1 (struct Effect *effect); | void apply_convolution_matrix1(struct Effect *effect); | ||||||
| 
 | 
 | ||||||
| #endif /* EFFECT_CONVMATR_H */ | #endif /* EFFECT_CONVMATR_H */ | ||||||
|  |  | ||||||
|  | @ -117,6 +117,9 @@ Effect *effect_new(Sprite *sprite, const char *name) | ||||||
|   effect->mask_address = NULL; |   effect->mask_address = NULL; | ||||||
|   effect->effect_data = effect_data; |   effect->effect_data = effect_data; | ||||||
|   effect->apply = apply; |   effect->apply = apply; | ||||||
|  |   effect->progress_data = NULL; | ||||||
|  |   effect->progress = NULL; | ||||||
|  |   effect->is_cancelled = NULL; | ||||||
| 
 | 
 | ||||||
|   effect_load_target(effect); |   effect_load_target(effect); | ||||||
| 
 | 
 | ||||||
|  | @ -266,27 +269,37 @@ bool effect_apply_step(Effect *effect) | ||||||
| 
 | 
 | ||||||
| void effect_apply(Effect *effect) | void effect_apply(Effect *effect) | ||||||
| { | { | ||||||
| /*   add_progress(effect->h); */ |   bool cancelled = FALSE; | ||||||
| 
 | 
 | ||||||
|   effect_begin(effect); |   effect_begin(effect); | ||||||
|   while (effect_apply_step(effect)) |   while (!cancelled && effect_apply_step(effect)) { | ||||||
|     ; |     if (effect->progress != NULL) | ||||||
| /*     do_progress(effect->row); */ |       (effect->progress)(effect->progress_data, | ||||||
|  | 			 effect->progress_base | ||||||
|  | 			 + effect->progress_width * (effect->row+1) / effect->h); | ||||||
| 
 | 
 | ||||||
|   /* undo stuff */ |     if (effect->is_cancelled != NULL) | ||||||
|   if (undo_is_enabled(effect->sprite->undo)) { |       cancelled = (effect->is_cancelled)(effect->progress_data); | ||||||
|     undo_set_label(effect->sprite->undo, |  | ||||||
| 		   effect->effect_data->label); |  | ||||||
|     undo_image(effect->sprite->undo, effect->src, |  | ||||||
| 	       effect->x, effect->y, effect->w, effect->h); |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   /* copy "dst" to "src" */ |   if (!cancelled) { | ||||||
|   image_copy(effect->src, effect->dst, 0, 0); |     /* undo stuff */ | ||||||
|  |     if (undo_is_enabled(effect->sprite->undo)) { | ||||||
|  |       undo_set_label(effect->sprite->undo, | ||||||
|  | 		     effect->effect_data->label); | ||||||
|  |       undo_image(effect->sprite->undo, effect->src, | ||||||
|  | 		 effect->x, effect->y, effect->w, effect->h); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
| /*   del_progress(); */ |     /* copy "dst" to "src" */ | ||||||
|  |     image_copy(effect->src, effect->dst, 0, 0); | ||||||
|  |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Updates the current editor to show the progress of the preview. | ||||||
|  |  */ | ||||||
| void effect_flush(Effect *effect) | void effect_flush(Effect *effect) | ||||||
| { | { | ||||||
|   if (effect->row >= 0) { |   if (effect->row >= 0) { | ||||||
|  | @ -329,6 +342,7 @@ void effect_apply_to_target(Effect *effect) | ||||||
|   int n, n2, images = 0; |   int n, n2, images = 0; | ||||||
|   Stock *stock; |   Stock *stock; | ||||||
|   int *x, *y; |   int *x, *y; | ||||||
|  |   bool cancelled = FALSE; | ||||||
| 
 | 
 | ||||||
|   stock = sprite_get_images(effect->sprite, target, TRUE, &x, &y); |   stock = sprite_get_images(effect->sprite, target, TRUE, &x, &y); | ||||||
|   if (!stock) |   if (!stock) | ||||||
|  | @ -339,24 +353,29 @@ void effect_apply_to_target(Effect *effect) | ||||||
|       images++; |       images++; | ||||||
| 
 | 
 | ||||||
|   if (images > 0) { |   if (images > 0) { | ||||||
|  |     /* open undo group of operations */ | ||||||
|     if (images > 1) { |     if (images > 1) { | ||||||
|       /* open undo */ |  | ||||||
|       if (undo_is_enabled(effect->sprite->undo)) |       if (undo_is_enabled(effect->sprite->undo)) | ||||||
| 	undo_open(effect->sprite->undo); | 	undo_open(effect->sprite->undo); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| /*     add_progress(images); */ |     effect->progress_base = 0.0f; | ||||||
|     for (n=n2=0; n<stock->nimage; n++) { |     effect->progress_width = 1.0f / images; | ||||||
|  | 
 | ||||||
|  |     for (n=n2=0; n<stock->nimage && !cancelled; n++) { | ||||||
|       if (!stock->image[n]) |       if (!stock->image[n]) | ||||||
| 	continue; | 	continue; | ||||||
| 
 | 
 | ||||||
| /*       do_progress(n2++); */ |  | ||||||
|       effect_apply_to_image(effect, stock->image[n], x[n], y[n]); |       effect_apply_to_image(effect, stock->image[n], x[n], y[n]); | ||||||
|     } |  | ||||||
| /*     del_progress(); */ |  | ||||||
| 
 | 
 | ||||||
|  |       if (effect->is_cancelled != NULL) | ||||||
|  | 	cancelled = (effect->is_cancelled)(effect->progress_data); | ||||||
|  | 
 | ||||||
|  |       effect->progress_base += effect->progress_width; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* close undo group of operations */ | ||||||
|     if (images > 1) { |     if (images > 1) { | ||||||
|       /* close  */ |  | ||||||
|       if (undo_is_enabled(effect->sprite->undo)) |       if (undo_is_enabled(effect->sprite->undo)) | ||||||
| 	undo_close(effect->sprite->undo); | 	undo_close(effect->sprite->undo); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -50,6 +50,11 @@ typedef struct Effect | ||||||
|     int a:1; |     int a:1; | ||||||
|     int index:1; |     int index:1; | ||||||
|   } target; |   } target; | ||||||
|  |   /* hooks */ | ||||||
|  |   float progress_base, progress_width; | ||||||
|  |   void *progress_data; | ||||||
|  |   void (*progress)(void *data, float progress); | ||||||
|  |   bool (*is_cancelled)(void *data); | ||||||
| } Effect; | } Effect; | ||||||
| 
 | 
 | ||||||
| Effect *effect_new(struct Sprite *sprite, const char *name); | Effect *effect_new(struct Sprite *sprite, const char *name); | ||||||
|  |  | ||||||
|  | @ -106,6 +106,7 @@ FileFormat format_ase = | ||||||
|   "ase,aseprite", |   "ase,aseprite", | ||||||
|   load_ASE, |   load_ASE, | ||||||
|   save_ASE, |   save_ASE, | ||||||
|  |   NULL, | ||||||
|   FILE_SUPPORT_RGB | |   FILE_SUPPORT_RGB | | ||||||
|   FILE_SUPPORT_RGBA | |   FILE_SUPPORT_RGBA | | ||||||
|   FILE_SUPPORT_GRAY | |   FILE_SUPPORT_GRAY | | ||||||
|  |  | ||||||
|  | @ -35,6 +35,7 @@ FileFormat format_bmp = | ||||||
|   "bmp", |   "bmp", | ||||||
|   load_BMP, |   load_BMP, | ||||||
|   save_BMP, |   save_BMP, | ||||||
|  |   NULL, | ||||||
|   FILE_SUPPORT_RGB | |   FILE_SUPPORT_RGB | | ||||||
|   FILE_SUPPORT_GRAY | |   FILE_SUPPORT_GRAY | | ||||||
|   FILE_SUPPORT_INDEXED | |   FILE_SUPPORT_INDEXED | | ||||||
|  | @ -678,7 +679,7 @@ static bool load_BMP(FileOp *fop) | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   /* setup the file-data */ |   /* setup the file-data */ | ||||||
|   if (fop_sequence_get_filedata(fop) == NULL) { |   if (fop->seq.filedata == NULL) { | ||||||
|     BmpData *bmpdata = bmpdata_new(); |     BmpData *bmpdata = bmpdata_new(); | ||||||
| 
 | 
 | ||||||
|     bmpdata->format = format; |     bmpdata->format = format; | ||||||
|  |  | ||||||
|  | @ -320,7 +320,7 @@ FileOp *fop_to_save_sprite(Sprite *sprite) | ||||||
|   if (jlist_length(fop->sprite->palettes) > 1) { |   if (jlist_length(fop->sprite->palettes) > 1) { | ||||||
|     if (!(fop->format->flags & (FILE_SUPPORT_PALETTES | |     if (!(fop->format->flags & (FILE_SUPPORT_PALETTES | | ||||||
| 				FILE_SUPPORT_SEQUENCES))) { | 				FILE_SUPPORT_SEQUENCES))) { | ||||||
|       usprintf(buf+ustrlen(buf), "<<- %s", _("Palette changes")); |       usprintf(buf+ustrlen(buf), "<<- %s", _("Palette changes between frames")); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | @ -414,6 +414,20 @@ FileOp *fop_to_save_sprite(Sprite *sprite) | ||||||
|   else |   else | ||||||
|     fop->filename = jstrdup(fop->sprite->filename); |     fop->filename = jstrdup(fop->sprite->filename); | ||||||
| 
 | 
 | ||||||
|  |   /* configure output format? */ | ||||||
|  |   if (fop->format->getdata) { | ||||||
|  |     FileData *data = (fop->format->getdata)(fop); | ||||||
|  | 
 | ||||||
|  |     /* does the user cancelled the operation? */ | ||||||
|  |     if (data == NULL) { | ||||||
|  |       fop_free(fop); | ||||||
|  |       return NULL; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fop->seq.filedata = data; | ||||||
|  |     sprite_set_filedata(fop->sprite, data); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   return fop; |   return fop; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -470,6 +484,7 @@ void fop_operate(FileOp *fop) | ||||||
|       frame = 0; |       frame = 0; | ||||||
|       old_image = NULL; |       old_image = NULL; | ||||||
|        |        | ||||||
|  |       fop->seq.has_alpha = FALSE; | ||||||
|       fop->seq.progress_offset = 0.0f; |       fop->seq.progress_offset = 0.0f; | ||||||
|       fop->seq.progress_fraction = 1.0f / (float)frames; |       fop->seq.progress_fraction = 1.0f / (float)frames; | ||||||
| 
 | 
 | ||||||
|  | @ -539,6 +554,10 @@ void fop_operate(FileOp *fop) | ||||||
| 
 | 
 | ||||||
|       /* final setup */ |       /* final setup */ | ||||||
|       if (fop->sprite != NULL) { |       if (fop->sprite != NULL) { | ||||||
|  | 	/* configure the layer as the `Background' */ | ||||||
|  | 	if (!fop->seq.has_alpha) | ||||||
|  | 	  layer_configure_as_background(fop->seq.layer); | ||||||
|  | 
 | ||||||
| 	/* set the frames range */ | 	/* set the frames range */ | ||||||
| 	sprite_set_frames(fop->sprite, frame); | 	sprite_set_frames(fop->sprite, frame); | ||||||
| 
 | 
 | ||||||
|  | @ -691,11 +710,6 @@ void fop_sequence_set_filedata(FileOp *fop, FileData *filedata) | ||||||
|   fop->seq.filedata = filedata; |   fop->seq.filedata = filedata; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| FileData *fop_sequence_get_filedata(FileOp *fop) |  | ||||||
| { |  | ||||||
|   return fop->seq.filedata; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void fop_sequence_set_color(FileOp *fop, int index, int r, int g, int b) | void fop_sequence_set_color(FileOp *fop, int index, int r, int g, int b) | ||||||
| { | { | ||||||
|   palette_set_entry(fop->seq.palette, index, _rgba(r, g, b, 255)); |   palette_set_entry(fop->seq.palette, index, _rgba(r, g, b, 255)); | ||||||
|  | @ -731,9 +745,6 @@ Image *fop_sequence_image(FileOp *fop, int imgtype, int w, int h) | ||||||
|     /* add the layer */ |     /* add the layer */ | ||||||
|     layer_add_layer(sprite->set, layer); |     layer_add_layer(sprite->set, layer); | ||||||
| 
 | 
 | ||||||
|     /* configure the layer as the background */ |  | ||||||
|     layer_configure_as_background(layer); |  | ||||||
| 
 |  | ||||||
|     /* done */ |     /* done */ | ||||||
|     fop->sprite = sprite; |     fop->sprite = sprite; | ||||||
|     fop->seq.layer = layer; |     fop->seq.layer = layer; | ||||||
|  |  | ||||||
|  | @ -50,10 +50,14 @@ struct FileFormat; | ||||||
| struct FileOp; | struct FileOp; | ||||||
| 
 | 
 | ||||||
| /* file operations */ | /* file operations */ | ||||||
| typedef enum { FileOpLoad, FileOpSave } FileOpType; | typedef enum { FileOpLoad, | ||||||
|  | 	       FileOpSave } FileOpType; | ||||||
|  | 
 | ||||||
| typedef bool (*FileLoad)(struct FileOp *fop); | typedef bool (*FileLoad)(struct FileOp *fop); | ||||||
| typedef bool (*FileSave)(struct FileOp *fop); | typedef bool (*FileSave)(struct FileOp *fop); | ||||||
| 
 | 
 | ||||||
|  | typedef struct FileData *(*FileGetData)(struct FileOp *fop); | ||||||
|  | 
 | ||||||
| /* load or/and save a file format */ | /* load or/and save a file format */ | ||||||
| typedef struct FileFormat | typedef struct FileFormat | ||||||
| { | { | ||||||
|  | @ -61,6 +65,7 @@ typedef struct FileFormat | ||||||
|   const char *exts;	/* extensions (e.g. "jpeg,jpg") */ |   const char *exts;	/* extensions (e.g. "jpeg,jpg") */ | ||||||
|   FileLoad load;	/* procedure to read a sprite in this format */ |   FileLoad load;	/* procedure to read a sprite in this format */ | ||||||
|   FileSave save;	/* procedure to write a sprite in this format */ |   FileSave save;	/* procedure to write a sprite in this format */ | ||||||
|  |   FileGetData getdata;  /* procedure to configure the format to be saved */ | ||||||
|   int flags; |   int flags; | ||||||
| } FileFormat; | } FileFormat; | ||||||
| 
 | 
 | ||||||
|  | @ -92,6 +97,7 @@ typedef struct FileOp | ||||||
|     float progress_fraction;	/* progress fraction for one frame */ |     float progress_fraction;	/* progress fraction for one frame */ | ||||||
|     /* to load sequences */ |     /* to load sequences */ | ||||||
|     int frame; |     int frame; | ||||||
|  |     bool has_alpha; | ||||||
|     struct Layer *layer; |     struct Layer *layer; | ||||||
|     struct Cel *last_cel; |     struct Cel *last_cel; | ||||||
|     struct FileData *filedata; |     struct FileData *filedata; | ||||||
|  | @ -118,8 +124,6 @@ void fop_stop(FileOp *fop); | ||||||
| void fop_free(FileOp *fop); | void fop_free(FileOp *fop); | ||||||
| 
 | 
 | ||||||
| void fop_sequence_set_filedata(FileOp *fop, struct FileData *filedata); | void fop_sequence_set_filedata(FileOp *fop, struct FileData *filedata); | ||||||
| struct FileData *fop_sequence_get_filedata(FileOp *fop); |  | ||||||
| 
 |  | ||||||
| void fop_sequence_set_color(FileOp *fop, int index, int r, int g, int b); | void fop_sequence_set_color(FileOp *fop, int index, int r, int g, int b); | ||||||
| void fop_sequence_get_color(FileOp *fop, int index, int *r, int *g, int *b); | void fop_sequence_get_color(FileOp *fop, int index, int *r, int *g, int *b); | ||||||
| struct Image *fop_sequence_image(FileOp *fi, int imgtype, int w, int h); | struct Image *fop_sequence_image(FileOp *fi, int imgtype, int w, int h); | ||||||
|  |  | ||||||
|  | @ -56,3 +56,14 @@ BmpData *bmpdata_new(void) | ||||||
| 
 | 
 | ||||||
|   return bmpdata; |   return bmpdata; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | JpegData *jpegdata_new(void) | ||||||
|  | { | ||||||
|  |   JpegData *jpegdata = (JpegData *)filedata_new(FILEDATA_JPEG, | ||||||
|  | 						sizeof(JpegData)); | ||||||
|  | 
 | ||||||
|  |   if (jpegdata == NULL) | ||||||
|  |     return NULL; | ||||||
|  | 
 | ||||||
|  |   return jpegdata; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -21,6 +21,7 @@ | ||||||
| 
 | 
 | ||||||
| enum { | enum { | ||||||
|   FILEDATA_BMP, |   FILEDATA_BMP, | ||||||
|  |   FILEDATA_JPEG, | ||||||
|   FILEDATA_MAX |   FILEDATA_MAX | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | @ -60,4 +61,23 @@ typedef struct BmpData | ||||||
| 
 | 
 | ||||||
| BmpData *bmpdata_new(void); | BmpData *bmpdata_new(void); | ||||||
| 
 | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  Data for JPEG files | ||||||
|  |  *********************************************************************/ | ||||||
|  | 
 | ||||||
|  | #define JPEGDATA_METHOD_SLOW		0 /* slow but accurate integer algorithm */ | ||||||
|  | #define JPEGDATA_METHOD_FAST		1 /* faster, less accurate integer method */ | ||||||
|  | #define JPEGDATA_METHOD_FLOAT		2 /* floating-point: accurate, fast on fast HW */ | ||||||
|  | #define JPEGDATA_METHOD_DEFAULT		JPEGDATA_METHOD_SLOW | ||||||
|  | 
 | ||||||
|  | typedef struct JpegData | ||||||
|  | { | ||||||
|  |   FileData head; | ||||||
|  |   float quality;		/* 1.0 maximum quality */ | ||||||
|  |   float smooth;			/* 1.0 maximum smooth */ | ||||||
|  |   int method; | ||||||
|  | } JpegData; | ||||||
|  | 
 | ||||||
|  | JpegData *jpegdata_new(void); | ||||||
|  | 
 | ||||||
| #endif /* FILEDATA_H */ | #endif /* FILEDATA_H */ | ||||||
|  |  | ||||||
|  | @ -37,6 +37,7 @@ FileFormat format_fli = | ||||||
|   "flc,fli", |   "flc,fli", | ||||||
|   load_FLI, |   load_FLI, | ||||||
|   save_FLI, |   save_FLI, | ||||||
|  |   NULL, | ||||||
|   FILE_SUPPORT_INDEXED | |   FILE_SUPPORT_INDEXED | | ||||||
|   FILE_SUPPORT_FRAMES | |   FILE_SUPPORT_FRAMES | | ||||||
|   FILE_SUPPORT_PALETTES |   FILE_SUPPORT_PALETTES | ||||||
|  | @ -104,8 +105,8 @@ static bool load_FLI(FileOp *fop) | ||||||
|   /* create the image */ |   /* create the image */ | ||||||
|   sprite = sprite_new(IMAGE_INDEXED, w, h); |   sprite = sprite_new(IMAGE_INDEXED, w, h); | ||||||
|   layer = layer_new(sprite); |   layer = layer_new(sprite); | ||||||
|   layer_set_name(layer, _("Background")); |  | ||||||
|   layer_add_layer(sprite->set, layer); |   layer_add_layer(sprite->set, layer); | ||||||
|  |   layer_configure_as_background(layer); | ||||||
| 
 | 
 | ||||||
|   /* set frames and speed */ |   /* set frames and speed */ | ||||||
|   sprite_set_frames(sprite, fli_header.frames); |   sprite_set_frames(sprite, fli_header.frames); | ||||||
|  |  | ||||||
|  | @ -47,12 +47,12 @@ FileFormat format_gif = | ||||||
|   "gif", |   "gif", | ||||||
|   load_GIF, |   load_GIF, | ||||||
|   save_GIF, |   save_GIF, | ||||||
|  |   NULL, | ||||||
|   FILE_SUPPORT_INDEXED | |   FILE_SUPPORT_INDEXED | | ||||||
|   FILE_SUPPORT_FRAMES | |   FILE_SUPPORT_FRAMES | | ||||||
|   FILE_SUPPORT_PALETTES |   FILE_SUPPORT_PALETTES | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| static void render_gif_frame(GIF_FRAME *frame, Image *image, | static void render_gif_frame(GIF_FRAME *frame, Image *image, | ||||||
| 			     int x, int y, int w, int h) | 			     int x, int y, int w, int h) | ||||||
| { | { | ||||||
|  | @ -117,7 +117,7 @@ static bool load_GIF(FileOp *fop) | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   layer_add_layer(sprite->set, layer); |   layer_add_layer(sprite->set, layer); | ||||||
|   layer_set_name(layer, _("Base")); |   layer_configure_as_background(layer); | ||||||
| 
 | 
 | ||||||
|   image_clear(current_image, gif->background_index); |   image_clear(current_image, gif->background_index); | ||||||
|   image_clear(current_image_old, gif->background_index); |   image_clear(current_image_old, gif->background_index); | ||||||
|  |  | ||||||
|  | @ -34,6 +34,7 @@ FileFormat format_ico = | ||||||
|   "ico", |   "ico", | ||||||
|   NULL, /* load_ICO, */ |   NULL, /* load_ICO, */ | ||||||
|   save_ICO, |   save_ICO, | ||||||
|  |   NULL, | ||||||
| /*   FILE_SUPPORT_RGB | */ | /*   FILE_SUPPORT_RGB | */ | ||||||
| /*   FILE_SUPPORT_GRAY | */ | /*   FILE_SUPPORT_GRAY | */ | ||||||
|   FILE_SUPPORT_INDEXED |   FILE_SUPPORT_INDEXED | ||||||
|  |  | ||||||
|  | @ -28,6 +28,7 @@ | ||||||
| #include "core/cfg.h" | #include "core/cfg.h" | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
| #include "file/file.h" | #include "file/file.h" | ||||||
|  | #include "file/filedata.h" | ||||||
| #include "raster/raster.h" | #include "raster/raster.h" | ||||||
| #include "script/script.h" | #include "script/script.h" | ||||||
| 
 | 
 | ||||||
|  | @ -35,8 +36,7 @@ | ||||||
| 
 | 
 | ||||||
| static bool load_JPEG(FileOp *fop); | static bool load_JPEG(FileOp *fop); | ||||||
| static bool save_JPEG(FileOp *fop); | static bool save_JPEG(FileOp *fop); | ||||||
| 
 | static JpegData *getdata_JPEG(FileOp *fop); | ||||||
| static bool configure_jpeg(void); /* TODO warning: not thread safe */ |  | ||||||
| 
 | 
 | ||||||
| FileFormat format_jpeg = | FileFormat format_jpeg = | ||||||
| { | { | ||||||
|  | @ -44,6 +44,7 @@ FileFormat format_jpeg = | ||||||
|   "jpeg,jpg", |   "jpeg,jpg", | ||||||
|   load_JPEG, |   load_JPEG, | ||||||
|   save_JPEG, |   save_JPEG, | ||||||
|  |   getdata_JPEG, | ||||||
|   FILE_SUPPORT_RGB | |   FILE_SUPPORT_RGB | | ||||||
|   FILE_SUPPORT_GRAY | |   FILE_SUPPORT_GRAY | | ||||||
|   FILE_SUPPORT_SEQUENCES |   FILE_SUPPORT_SEQUENCES | ||||||
|  | @ -228,19 +229,8 @@ static bool save_JPEG(FileOp *fop) | ||||||
|   FILE *file; |   FILE *file; | ||||||
|   JSAMPARRAY buffer; |   JSAMPARRAY buffer; | ||||||
|   JDIMENSION buffer_height; |   JDIMENSION buffer_height; | ||||||
|  |   JpegData *jpegdata = (JpegData *)fop->seq.filedata; | ||||||
|   int c; |   int c; | ||||||
|   int smooth; |  | ||||||
|   int quality; |  | ||||||
|   J_DCT_METHOD method; |  | ||||||
| 
 |  | ||||||
|   /* Configure JPEG compression only in the first frame.  */ |  | ||||||
|   if (fop->sprite->frame == 0 && !configure_jpeg()) |  | ||||||
|     return FALSE; |  | ||||||
| 
 |  | ||||||
|   /* Options.  */ |  | ||||||
|   smooth = get_config_int("JPEG", "Smooth", 0); |  | ||||||
|   quality = get_config_int("JPEG", "Quality", 100); |  | ||||||
|   method = get_config_int("JPEG", "Method", JDCT_DEFAULT); |  | ||||||
| 
 | 
 | ||||||
|   /* Open the file for write in it.  */ |   /* Open the file for write in it.  */ | ||||||
|   file = fopen(fop->filename, "wb"); |   file = fopen(fop->filename, "wb"); | ||||||
|  | @ -271,9 +261,9 @@ static bool save_JPEG(FileOp *fop) | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   jpeg_set_defaults(&cinfo); |   jpeg_set_defaults(&cinfo); | ||||||
|   jpeg_set_quality(&cinfo, quality, TRUE); |   jpeg_set_quality(&cinfo, (int)MID(0, 100.0f * jpegdata->quality, 100), TRUE); | ||||||
|   cinfo.dct_method = method; |   cinfo.dct_method = jpegdata->method; | ||||||
|   cinfo.smoothing_factor = smooth; |   cinfo.smoothing_factor = (int)MID(0, 100.0f * jpegdata->smooth, 100); | ||||||
| 
 | 
 | ||||||
|   /* Start compressor.  */ |   /* Start compressor.  */ | ||||||
|   jpeg_start_compress(&cinfo, TRUE); |   jpeg_start_compress(&cinfo, TRUE); | ||||||
|  | @ -358,26 +348,25 @@ static bool save_JPEG(FileOp *fop) | ||||||
| /**
 | /**
 | ||||||
|  * Shows the JPEG configuration dialog. |  * Shows the JPEG configuration dialog. | ||||||
|  */ |  */ | ||||||
| static bool configure_jpeg(void) | static JpegData *getdata_JPEG(FileOp *fop) | ||||||
| { | { | ||||||
|   JWidget window, box1, box2, box3, box4, box5; |   JWidget window, box1, box2, box3, box4, box5; | ||||||
|   JWidget label_quality, label_smooth, label_method; |   JWidget label_quality, label_smooth, label_method; | ||||||
|   JWidget slider_quality, slider_smooth, view_method; |   JWidget slider_quality, slider_smooth, view_method; | ||||||
|   JWidget list_method, button_ok, button_cancel; |   JWidget list_method, button_ok, button_cancel; | ||||||
|   int quality, smooth, method; |   JpegData *jpegdata = jpegdata_new(); | ||||||
|   bool ret; | 
 | ||||||
|  |   /* configuration parameters */ | ||||||
|  |   jpegdata->quality = get_config_float("JPEG", "Quality", 0.6f); | ||||||
|  |   jpegdata->smooth = 0.0f; | ||||||
|  |   jpegdata->method = JPEGDATA_METHOD_DEFAULT; | ||||||
| 
 | 
 | ||||||
|   /* interactive mode */ |   /* interactive mode */ | ||||||
|   if (!is_interactive()) |   if (!is_interactive()) | ||||||
|     return TRUE; |     return jpegdata; | ||||||
| 
 |  | ||||||
|   /* configuration parameters */ |  | ||||||
|   quality = get_config_int("JPEG", "Quality", 100); |  | ||||||
|   smooth = get_config_int("JPEG", "Smooth", 0); |  | ||||||
|   method = get_config_int("JPEG", "Method", 0); |  | ||||||
| 
 | 
 | ||||||
|   /* widgets */ |   /* widgets */ | ||||||
|   window = jwindow_new(_("Configure JPEG Compression")); |   window = jwindow_new(_("JPEG Options")); | ||||||
|   box1 = jbox_new(JI_VERTICAL); |   box1 = jbox_new(JI_VERTICAL); | ||||||
|   box2 = jbox_new(JI_HORIZONTAL); |   box2 = jbox_new(JI_HORIZONTAL); | ||||||
|   box3 = jbox_new(JI_VERTICAL + JI_HOMOGENEOUS); |   box3 = jbox_new(JI_VERTICAL + JI_HOMOGENEOUS); | ||||||
|  | @ -386,8 +375,8 @@ static bool configure_jpeg(void) | ||||||
|   label_quality = jlabel_new(_("Quality:")); |   label_quality = jlabel_new(_("Quality:")); | ||||||
|   label_smooth = jlabel_new(_("Smooth:")); |   label_smooth = jlabel_new(_("Smooth:")); | ||||||
|   label_method = jlabel_new(_("Method:")); |   label_method = jlabel_new(_("Method:")); | ||||||
|   slider_quality = jslider_new(0, 100, quality); |   slider_quality = jslider_new(0, 10, jpegdata->quality*10); | ||||||
|   slider_smooth = jslider_new(0, 100, smooth); |   slider_smooth = jslider_new(0, 10, jpegdata->smooth*10); | ||||||
|   view_method = jview_new(); |   view_method = jview_new(); | ||||||
|   list_method = jlistbox_new(); |   list_method = jlistbox_new(); | ||||||
|   button_ok = jbutton_new(_("&OK")); |   button_ok = jbutton_new(_("&OK")); | ||||||
|  | @ -396,13 +385,14 @@ static bool configure_jpeg(void) | ||||||
|   jwidget_add_child(list_method, jlistitem_new(_("Slow"))); |   jwidget_add_child(list_method, jlistitem_new(_("Slow"))); | ||||||
|   jwidget_add_child(list_method, jlistitem_new(_("Fast"))); |   jwidget_add_child(list_method, jlistitem_new(_("Fast"))); | ||||||
|   jwidget_add_child(list_method, jlistitem_new(_("Float"))); |   jwidget_add_child(list_method, jlistitem_new(_("Float"))); | ||||||
|   jlistbox_select_index(list_method, method); |   jlistbox_select_index(list_method, jpegdata->method); | ||||||
| 
 | 
 | ||||||
|     jview_attach(view_method, list_method); |   jview_attach(view_method, list_method); | ||||||
|   jview_maxsize(view_method); |   jview_maxsize(view_method); | ||||||
| 
 | 
 | ||||||
|   jwidget_expansive(box4, TRUE); |   jwidget_expansive(box4, TRUE); | ||||||
|   jwidget_expansive(view_method, TRUE); |   jwidget_expansive(view_method, TRUE); | ||||||
|  |   jwidget_magnetic(button_ok, TRUE); | ||||||
| 
 | 
 | ||||||
|   jwidget_add_child(box3, label_quality); |   jwidget_add_child(box3, label_quality); | ||||||
|   jwidget_add_child(box3, label_smooth); |   jwidget_add_child(box3, label_smooth); | ||||||
|  | @ -421,19 +411,17 @@ static bool configure_jpeg(void) | ||||||
|   jwindow_open_fg(window); |   jwindow_open_fg(window); | ||||||
| 
 | 
 | ||||||
|   if (jwindow_get_killer(window) == button_ok) { |   if (jwindow_get_killer(window) == button_ok) { | ||||||
|     ret = TRUE; |     jpegdata->quality = jslider_get_value(slider_quality) / 10.0f; | ||||||
|  |     jpegdata->smooth = jslider_get_value(slider_smooth) / 10.0f; | ||||||
|  |     jpegdata->method = jlistbox_get_selected_index(list_method); | ||||||
| 
 | 
 | ||||||
|     quality = jslider_get_value(slider_quality); |     set_config_float("JPEG", "Quality", jpegdata->quality); | ||||||
|     smooth = jslider_get_value(slider_smooth); |   } | ||||||
|     method = jlistbox_get_selected_index(list_method); |   else { | ||||||
| 
 |     filedata_free((FileData *)jpegdata); | ||||||
|     set_config_int("JPEG", "Quality", quality); |     jpegdata = NULL; | ||||||
|     set_config_int("JPEG", "Smooth", smooth); |  | ||||||
|     set_config_int("JPEG", "Method", method); |  | ||||||
|   } |   } | ||||||
|   else |  | ||||||
|     ret = FALSE; |  | ||||||
| 
 | 
 | ||||||
|   jwidget_free(window); |   jwidget_free(window); | ||||||
|   return ret; |   return jpegdata; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -34,6 +34,7 @@ FileFormat format_pcx = | ||||||
|   "pcx", |   "pcx", | ||||||
|   load_PCX, |   load_PCX, | ||||||
|   save_PCX, |   save_PCX, | ||||||
|  |   NULL, | ||||||
|   FILE_SUPPORT_RGB | |   FILE_SUPPORT_RGB | | ||||||
|   FILE_SUPPORT_GRAY | |   FILE_SUPPORT_GRAY | | ||||||
|   FILE_SUPPORT_INDEXED | |   FILE_SUPPORT_INDEXED | | ||||||
|  |  | ||||||
|  | @ -42,6 +42,7 @@ FileFormat format_png = | ||||||
|   "png", |   "png", | ||||||
|   load_PNG, |   load_PNG, | ||||||
|   save_PNG, |   save_PNG, | ||||||
|  |   NULL, | ||||||
|   FILE_SUPPORT_RGB | |   FILE_SUPPORT_RGB | | ||||||
|   FILE_SUPPORT_RGBA | |   FILE_SUPPORT_RGBA | | ||||||
|   FILE_SUPPORT_GRAY | |   FILE_SUPPORT_GRAY | | ||||||
|  | @ -155,17 +156,23 @@ static bool load_PNG(FileOp *fop) | ||||||
| 
 | 
 | ||||||
|   /* create the output image */ |   /* create the output image */ | ||||||
|   switch (info_ptr->color_type) { |   switch (info_ptr->color_type) { | ||||||
|     case PNG_COLOR_TYPE_RGB:  | 
 | ||||||
|     case PNG_COLOR_TYPE_RGB_ALPHA: |     case PNG_COLOR_TYPE_RGB_ALPHA: | ||||||
|  |       fop->seq.has_alpha = TRUE; | ||||||
|  |     case PNG_COLOR_TYPE_RGB:  | ||||||
|       imgtype = IMAGE_RGB; |       imgtype = IMAGE_RGB; | ||||||
|       break; |       break; | ||||||
|     case PNG_COLOR_TYPE_GRAY: | 
 | ||||||
|     case PNG_COLOR_TYPE_GRAY_ALPHA: |     case PNG_COLOR_TYPE_GRAY_ALPHA: | ||||||
|  |       fop->seq.has_alpha = TRUE; | ||||||
|  |     case PNG_COLOR_TYPE_GRAY: | ||||||
|       imgtype = IMAGE_GRAYSCALE; |       imgtype = IMAGE_GRAYSCALE; | ||||||
|       break; |       break; | ||||||
|  | 
 | ||||||
|     case PNG_COLOR_TYPE_PALETTE: |     case PNG_COLOR_TYPE_PALETTE: | ||||||
|       imgtype = IMAGE_INDEXED; |       imgtype = IMAGE_INDEXED; | ||||||
|       break; |       break; | ||||||
|  | 
 | ||||||
|     default: |     default: | ||||||
|       fop_error(fop, "Color type not supported\n)"); |       fop_error(fop, "Color type not supported\n)"); | ||||||
|       png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); |       png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); | ||||||
|  |  | ||||||
|  | @ -37,6 +37,7 @@ FileFormat format_tga = | ||||||
|   "tga", |   "tga", | ||||||
|   load_TGA, |   load_TGA, | ||||||
|   save_TGA, |   save_TGA, | ||||||
|  |   NULL, | ||||||
|   FILE_SUPPORT_RGB | |   FILE_SUPPORT_RGB | | ||||||
|   FILE_SUPPORT_RGBA | |   FILE_SUPPORT_RGBA | | ||||||
|   FILE_SUPPORT_GRAY | |   FILE_SUPPORT_GRAY | | ||||||
|  |  | ||||||
|  | @ -54,6 +54,8 @@ | ||||||
| #define REBUILD_RECENT_LIST	2 | #define REBUILD_RECENT_LIST	2 | ||||||
| #define REFRESH_FULL_SCREEN	4 | #define REFRESH_FULL_SCREEN	4 | ||||||
| 
 | 
 | ||||||
|  | #define MONITOR_TIMER_MSECS	100 | ||||||
|  | 
 | ||||||
| /**************************************************************/ | /**************************************************************/ | ||||||
| 
 | 
 | ||||||
| #ifdef ALLEGRO_WINDOWS | #ifdef ALLEGRO_WINDOWS | ||||||
|  | @ -573,7 +575,7 @@ JWidget load_widget(const char *filename, const char *name) | ||||||
|   return widget; |   return widget; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void rebuild_recent_list(void) | void schedule_rebuild_recent_list(void) | ||||||
| { | { | ||||||
|   next_idle_flags |= REBUILD_RECENT_LIST; |   next_idle_flags |= REBUILD_RECENT_LIST; | ||||||
| } | } | ||||||
|  | @ -740,7 +742,7 @@ Monitor *add_gui_monitor(void (*proc)(void *), | ||||||
|   jlist_append(monitors, monitor); |   jlist_append(monitors, monitor); | ||||||
| 
 | 
 | ||||||
|   if (monitor_timer < 0) |   if (monitor_timer < 0) | ||||||
|     monitor_timer = jmanager_add_timer(manager, 100); |     monitor_timer = jmanager_add_timer(manager, MONITOR_TIMER_MSECS); | ||||||
| 
 | 
 | ||||||
|   jmanager_start_timer(monitor_timer); |   jmanager_start_timer(monitor_timer); | ||||||
| 
 | 
 | ||||||
|  | @ -748,7 +750,7 @@ Monitor *add_gui_monitor(void (*proc)(void *), | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Removes a previously added monitor. |  * Removes and frees a previously added monitor. | ||||||
|  */ |  */ | ||||||
| void remove_gui_monitor(Monitor *monitor) | void remove_gui_monitor(Monitor *monitor) | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -50,7 +50,7 @@ void save_window_pos(JWidget window, const char *section); | ||||||
| 
 | 
 | ||||||
| JWidget load_widget(const char *filename, const char *name); | JWidget load_widget(const char *filename, const char *name); | ||||||
| 
 | 
 | ||||||
| void rebuild_recent_list(void); | void schedule_rebuild_recent_list(void); | ||||||
| 
 | 
 | ||||||
| void hook_signal(JWidget widget, | void hook_signal(JWidget widget, | ||||||
| 		 int signal_num, | 		 int signal_num, | ||||||
|  |  | ||||||
|  | @ -88,7 +88,7 @@ void recent_file(const char *filename) | ||||||
|       if (strcmp(filename, filename_it) == 0) { |       if (strcmp(filename, filename_it) == 0) { | ||||||
| 	jlist_remove(recent_files, filename_it); | 	jlist_remove(recent_files, filename_it); | ||||||
| 	jlist_prepend(recent_files, filename_it); | 	jlist_prepend(recent_files, filename_it); | ||||||
| 	rebuild_recent_list(); | 	schedule_rebuild_recent_list(); | ||||||
| 	return; | 	return; | ||||||
|       } |       } | ||||||
|       count++; |       count++; | ||||||
|  | @ -103,7 +103,7 @@ void recent_file(const char *filename) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     jlist_prepend(recent_files, jstrdup(filename)); |     jlist_prepend(recent_files, jstrdup(filename)); | ||||||
|     rebuild_recent_list(); |     schedule_rebuild_recent_list(); | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -118,7 +118,7 @@ void unrecent_file(const char *filename) | ||||||
|       if (strcmp(filename, filename_it) == 0) { |       if (strcmp(filename, filename_it) == 0) { | ||||||
| 	jfree(filename_it); | 	jfree(filename_it); | ||||||
| 	jlist_delete_link(recent_files, link); | 	jlist_delete_link(recent_files, link); | ||||||
| 	rebuild_recent_list(); | 	schedule_rebuild_recent_list(); | ||||||
| 	break; | 	break; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -102,6 +102,8 @@ static bool preview_msg_proc(JWidget widget, JMessage msg) | ||||||
| 
 | 
 | ||||||
|     case JM_CLOSE: |     case JM_CLOSE: | ||||||
|       set_preview_image(NULL, NULL); |       set_preview_image(NULL, NULL); | ||||||
|  |       /* stop the preview timer */ | ||||||
|  |       jmanager_stop_timer(preview->timer_id); | ||||||
|       break; |       break; | ||||||
| 
 | 
 | ||||||
|     case JM_TIMER: |     case JM_TIMER: | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue