| 
									
										
										
										
											2007-11-17 02:25:45 +08:00
										 |  |  | /* ASE - Allegro Sprite Editor
 | 
					
						
							| 
									
										
										
										
											2010-02-02 05:25:40 +08:00
										 |  |  |  * Copyright (C) 2001-2010  David Capello | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * 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"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | #include <assert.h>
 | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | #include <string.h>
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | #include <allegro.h>
 | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-05 09:30:50 +08:00
										 |  |  | #include "jinete/jalert.h"
 | 
					
						
							|  |  |  | #include "jinete/jlist.h"
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | #include "jinete/jmutex.h"
 | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-18 03:32:09 +08:00
										 |  |  | #include "console.h"
 | 
					
						
							| 
									
										
										
										
											2009-12-11 22:53:05 +08:00
										 |  |  | #include "app.h"
 | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | #include "core/core.h"
 | 
					
						
							|  |  |  | #include "file/file.h"
 | 
					
						
							| 
									
										
										
										
											2008-03-29 12:35:30 +08:00
										 |  |  | #include "file/format_options.h"
 | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | #include "modules/gui.h"
 | 
					
						
							| 
									
										
										
										
											2008-03-23 02:43:56 +08:00
										 |  |  | #include "modules/palettes.h"
 | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | #include "raster/raster.h"
 | 
					
						
							| 
									
										
										
										
											2007-09-30 23:32:21 +08:00
										 |  |  | #include "widgets/statebar.h"
 | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-05 09:30:50 +08:00
										 |  |  | extern FileFormat format_ase; | 
					
						
							|  |  |  | extern FileFormat format_bmp; | 
					
						
							|  |  |  | extern FileFormat format_fli; | 
					
						
							|  |  |  | extern FileFormat format_jpeg; | 
					
						
							|  |  |  | extern FileFormat format_pcx; | 
					
						
							|  |  |  | extern FileFormat format_tga; | 
					
						
							|  |  |  | extern FileFormat format_gif; | 
					
						
							|  |  |  | extern FileFormat format_ico; | 
					
						
							|  |  |  | extern FileFormat format_png; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static FileFormat *formats[] = | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   &format_ase, | 
					
						
							|  |  |  |   &format_bmp, | 
					
						
							|  |  |  |   &format_fli, | 
					
						
							|  |  |  |   &format_jpeg, | 
					
						
							|  |  |  |   &format_pcx, | 
					
						
							|  |  |  |   &format_tga, | 
					
						
							|  |  |  |   &format_gif, | 
					
						
							|  |  |  |   &format_ico, | 
					
						
							|  |  |  |   &format_png, | 
					
						
							|  |  |  |   NULL | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | static FileOp *fop_new(FileOpType type); | 
					
						
							|  |  |  | static void fop_prepare_for_sequence(FileOp *fop); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-05 09:30:50 +08:00
										 |  |  | static FileFormat *get_fileformat(const char *extension); | 
					
						
							| 
									
										
										
										
											2007-09-20 08:32:35 +08:00
										 |  |  | static int split_filename(const char *filename, char *left, char *right, int *width); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | void get_readable_extensions(char *buf, int size) | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | { | 
					
						
							|  |  |  |   int c; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* clear the string */ | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   ustrncpy(buf, empty_string, size); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-05 09:30:50 +08:00
										 |  |  |   /* insert file format */ | 
					
						
							|  |  |  |   for (c=0; formats[c]; c++) { | 
					
						
							|  |  |  |     if (formats[c]->load) | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |       ustrncat(buf, formats[c]->exts, size); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-05 09:30:50 +08:00
										 |  |  |     if (formats[c+1] && formats[c]->load) | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |       ustrncat(buf, ",", size); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | void get_writable_extensions(char *buf, int size) | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | { | 
					
						
							|  |  |  |   int c; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* clear the string */ | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   ustrncpy(buf, empty_string, size); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-05 09:30:50 +08:00
										 |  |  |   /* insert file format */ | 
					
						
							|  |  |  |   for (c=0; formats[c]; c++) { | 
					
						
							|  |  |  |     if (formats[c]->save) | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |       ustrncat(buf, formats[c]->exts, size); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-05 09:30:50 +08:00
										 |  |  |     if (formats[c+1] && formats[c]->save) | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |       ustrncat(buf, ",", size); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 08:32:35 +08:00
										 |  |  | Sprite *sprite_load(const char *filename) | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | { | 
					
						
							|  |  |  |   Sprite *sprite; | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  |   /* TODO add a option to configure what to do with the sequence */ | 
					
						
							|  |  |  |   FileOp *fop = fop_to_load_sprite(filename, FILE_LOAD_SEQUENCE_NONE); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   if (!fop) | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* operate in this same thread */ | 
					
						
							|  |  |  |   fop_operate(fop); | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  |   fop_done(fop); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-11 23:11:11 +08:00
										 |  |  |   if (fop->error) { | 
					
						
							|  |  |  |     Console console; | 
					
						
							|  |  |  |     console.printf(fop->error); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   sprite = fop->sprite; | 
					
						
							|  |  |  |   fop_free(fop); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return sprite; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int sprite_save(Sprite *sprite) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   int ret; | 
					
						
							|  |  |  |   FileOp *fop = fop_to_save_sprite(sprite); | 
					
						
							|  |  |  |   if (!fop) | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* operate in this same thread */ | 
					
						
							|  |  |  |   fop_operate(fop); | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  |   fop_done(fop); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-11 23:11:11 +08:00
										 |  |  |   if (fop->error) { | 
					
						
							|  |  |  |     Console console; | 
					
						
							|  |  |  |     console.printf(fop->error); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   ret = (fop->error == NULL) ? 0: -1; | 
					
						
							|  |  |  |   fop_free(fop); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  | FileOp *fop_to_load_sprite(const char *filename, int flags) | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | { | 
					
						
							|  |  |  |   char *extension; | 
					
						
							|  |  |  |   FileOp *fop; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   fop = fop_new(FileOpLoad); | 
					
						
							|  |  |  |   if (!fop) | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* get the extension of the filename (in lower case) */ | 
					
						
							|  |  |  |   extension = jstrdup(get_extension(filename)); | 
					
						
							| 
									
										
										
										
											2007-11-15 05:28:33 +08:00
										 |  |  |   ustrlwr(extension); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-15 05:28:33 +08:00
										 |  |  |   PRINTF("Loading file \"%s\" (%s)\n", filename, extension); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   /* does file exist? */ | 
					
						
							|  |  |  |   if (!file_exists(filename, FA_ALL, NULL)) { | 
					
						
							|  |  |  |     fop_error(fop, _("File not found: \"%s\"\n"), filename); | 
					
						
							|  |  |  |     goto done; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   /* get the format through the extension of the filename */ | 
					
						
							|  |  |  |   fop->format = get_fileformat(extension); | 
					
						
							|  |  |  |   if (!fop->format || | 
					
						
							|  |  |  |       !fop->format->load) { | 
					
						
							|  |  |  |     fop_error(fop, _("ASE can't load \"%s\" files\n"), extension); | 
					
						
							|  |  |  |     goto done; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* use the "sequence" interface */ | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   if (fop->format->flags & FILE_SUPPORT_SEQUENCES) { | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  |     /* prepare to load a sequence */ | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |     fop_prepare_for_sequence(fop); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* per now, we want load just one file */ | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |     jlist_append(fop->seq.filename_list, jstrdup(filename)); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  |     /* 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; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /* first of all, we must generate the list of files to load in the
 | 
					
						
							|  |  |  | 	 sequence... */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /* 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)); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  |       /* 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); | 
					
						
							|  |  |  | 	  } | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   else | 
					
						
							|  |  |  |     fop->filename = jstrdup(filename); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  |   /* load just one frame */ | 
					
						
							|  |  |  |   if (flags & FILE_LOAD_ONE_FRAME) | 
					
						
							| 
									
										
										
										
											2010-01-31 00:43:13 +08:00
										 |  |  |     fop->oneframe = true; | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | done:; | 
					
						
							|  |  |  |   jfree(extension); | 
					
						
							|  |  |  |   return fop; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | FileOp *fop_to_save_sprite(Sprite *sprite) | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | { | 
					
						
							|  |  |  |   char extension[32], buf[2048]; | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   FileOp *fop; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   bool fatal; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   fop = fop_new(FileOpSave); | 
					
						
							|  |  |  |   if (!fop) | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* sprite to save */ | 
					
						
							|  |  |  |   fop->sprite = sprite; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* get the extension of the filename (in lower case) */ | 
					
						
							|  |  |  |   ustrcpy(extension, get_extension(fop->sprite->filename)); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   ustrlwr(extension); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   PRINTF("Saving sprite \"%s\" (%s)\n", fop->sprite->filename, extension); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   /* get the format through the extension of the filename */ | 
					
						
							|  |  |  |   fop->format = get_fileformat(extension); | 
					
						
							|  |  |  |   if (!fop->format || | 
					
						
							|  |  |  |       !fop->format->save) { | 
					
						
							|  |  |  |     fop_error(fop, _("ASE can't save \"%s\" files\n"), extension); | 
					
						
							|  |  |  |     return fop; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* warnings */ | 
					
						
							|  |  |  |   ustrcpy(buf, empty_string); | 
					
						
							| 
									
										
										
										
											2010-01-31 00:43:13 +08:00
										 |  |  |   fatal = false; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* check image type support */ | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   switch (fop->sprite->imgtype) { | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     case IMAGE_RGB: | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |       if (!(fop->format->flags & FILE_SUPPORT_RGB)) { | 
					
						
							| 
									
										
										
										
											2007-11-28 22:19:36 +08:00
										 |  |  | 	usprintf(buf+ustrlen(buf), "<<- %s", _("RGB format")); | 
					
						
							| 
									
										
										
										
											2010-01-31 00:43:13 +08:00
										 |  |  | 	fatal = true; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |       if (!(fop->format->flags & FILE_SUPPORT_RGBA) && | 
					
						
							|  |  |  | 	  sprite_need_alpha(fop->sprite)) { | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 	usprintf(buf+ustrlen(buf), "<<- %s", _("Alpha channel")); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case IMAGE_GRAYSCALE: | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |       if (!(fop->format->flags & FILE_SUPPORT_GRAY)) { | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 	usprintf(buf+ustrlen(buf), "<<- %s", _("Grayscale format")); | 
					
						
							| 
									
										
										
										
											2010-01-31 00:43:13 +08:00
										 |  |  | 	fatal = true; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |       if (!(fop->format->flags & FILE_SUPPORT_GRAYA) && | 
					
						
							|  |  |  | 	  sprite_need_alpha(fop->sprite)) { | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 	usprintf(buf+ustrlen(buf), "<<- %s", _("Alpha channel")); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case IMAGE_INDEXED: | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |       if (!(fop->format->flags & FILE_SUPPORT_INDEXED)) { | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 	usprintf(buf+ustrlen(buf), "<<- %s", _("Indexed format")); | 
					
						
							| 
									
										
										
										
											2010-01-31 00:43:13 +08:00
										 |  |  | 	fatal = true; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |       } | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-17 21:12:26 +08:00
										 |  |  |   // check frames support
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   if (!(fop->format->flags & (FILE_SUPPORT_FRAMES | | 
					
						
							|  |  |  | 			      FILE_SUPPORT_SEQUENCES))) { | 
					
						
							|  |  |  |     if (fop->sprite->frames > 1) | 
					
						
							| 
									
										
										
										
											2007-11-28 22:19:36 +08:00
										 |  |  |       usprintf(buf+ustrlen(buf), "<<- %s", _("Frames")); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-17 21:12:26 +08:00
										 |  |  |   // layers support
 | 
					
						
							|  |  |  |   if (fop->sprite->get_folder()->get_layers_count() > 1) { | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |     if (!(fop->format->flags & FILE_SUPPORT_LAYERS)) { | 
					
						
							| 
									
										
										
										
											2007-11-28 22:19:36 +08:00
										 |  |  |       usprintf(buf+ustrlen(buf), "<<- %s", _("Layers")); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* palettes support */ | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   if (jlist_length(fop->sprite->palettes) > 1) { | 
					
						
							|  |  |  |     if (!(fop->format->flags & (FILE_SUPPORT_PALETTES | | 
					
						
							|  |  |  | 				FILE_SUPPORT_SEQUENCES))) { | 
					
						
							| 
									
										
										
										
											2008-03-29 11:43:19 +08:00
										 |  |  |       usprintf(buf+ustrlen(buf), "<<- %s", _("Palette changes between frames")); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* repositories */ | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   if (!jlist_empty(fop->sprite->repository.masks)) { | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |     Mask *mask; | 
					
						
							|  |  |  |     JLink link; | 
					
						
							|  |  |  |     int count = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |     JI_LIST_FOR_EACH(fop->sprite->repository.masks, link) { | 
					
						
							| 
									
										
										
										
											2008-10-01 05:01:54 +08:00
										 |  |  |       mask = reinterpret_cast<Mask*>(link->data); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       /* names starting with '*' are ignored */ | 
					
						
							|  |  |  |       if (mask->name && *mask->name == '*') | 
					
						
							|  |  |  | 	continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       count++; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |     if ((count > 0) && !(fop->format->flags & FILE_SUPPORT_MASKS_REPOSITORY)) { | 
					
						
							| 
									
										
										
										
											2007-11-28 22:19:36 +08:00
										 |  |  |       usprintf(buf+ustrlen(buf), "<<- %s", _("Mask Repository")); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   if (!jlist_empty(fop->sprite->repository.paths)) { | 
					
						
							|  |  |  |     if (!(fop->format->flags & FILE_SUPPORT_PATHS_REPOSITORY)) { | 
					
						
							| 
									
										
										
										
											2007-11-28 22:19:36 +08:00
										 |  |  |       usprintf(buf+ustrlen(buf), "<<- %s", _("Path Repository")); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* show the confirmation alert */ | 
					
						
							| 
									
										
										
										
											2007-09-30 23:32:21 +08:00
										 |  |  |   if (ugetc(buf)) { | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |     /* interative */ | 
					
						
							| 
									
										
										
										
											2007-09-30 23:32:21 +08:00
										 |  |  |     if (is_interactive()) { | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |       int ret; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |       if (fatal) | 
					
						
							| 
									
										
										
										
											2007-11-15 05:28:33 +08:00
										 |  |  | 	ret = jalert(_("Error<<File format \"%s\" doesn't support:%s" | 
					
						
							| 
									
										
										
										
											2007-09-30 23:32:21 +08:00
										 |  |  | 		       "||&Close"), | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 		     fop->format->name, buf); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |       else | 
					
						
							| 
									
										
										
										
											2007-11-15 05:28:33 +08:00
										 |  |  | 	ret = jalert(_("Warning<<File format \"%s\" doesn't support:%s" | 
					
						
							| 
									
										
										
										
											2007-09-30 23:32:21 +08:00
										 |  |  | 		       "<<Do you want continue?" | 
					
						
							|  |  |  | 		       "||&Yes||&No"), | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 		     fop->format->name, buf); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |       /* operation can't be done (by fatal error) or the user cancel
 | 
					
						
							|  |  |  | 	 the operation */ | 
					
						
							|  |  |  |       if ((fatal) || (ret != 1)) { | 
					
						
							|  |  |  | 	fop_free(fop); | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     /* no interactive & fatal error? */ | 
					
						
							|  |  |  |     else if (fatal) { | 
					
						
							|  |  |  |       fop_error(fop, buf); | 
					
						
							|  |  |  |       return fop; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* use the "sequence" interface */ | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   if (fop->format->flags & FILE_SUPPORT_SEQUENCES) { | 
					
						
							|  |  |  |     fop_prepare_for_sequence(fop); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* to save one frame */ | 
					
						
							|  |  |  |     if (fop->sprite->frames == 1) { | 
					
						
							|  |  |  |       jlist_append(fop->seq.filename_list, | 
					
						
							|  |  |  | 		   jstrdup(fop->sprite->filename)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     /* to save more frames */ | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       char buf[256], left[256], right[256]; | 
					
						
							|  |  |  |       int frame, width, start_from; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       start_from = split_filename(fop->sprite->filename, left, right, &width); | 
					
						
							|  |  |  |       if (start_from < 0) { | 
					
						
							|  |  |  | 	start_from = 0; | 
					
						
							|  |  |  | 	width = | 
					
						
							|  |  |  | 	  (fop->sprite->frames < 10)? 1: | 
					
						
							|  |  |  | 	  (fop->sprite->frames < 100)? 2: | 
					
						
							|  |  |  | 	  (fop->sprite->frames < 1000)? 3: 4; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       for (frame=0; frame<fop->sprite->frames; frame++) { | 
					
						
							|  |  |  | 	/* get the name for this frame */ | 
					
						
							|  |  |  | 	usprintf(buf, "%s%0*d%s", left, width, start_from+frame, right); | 
					
						
							|  |  |  | 	jlist_append(fop->seq.filename_list, jstrdup(buf)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     fop->filename = jstrdup(fop->sprite->filename); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-29 11:43:19 +08:00
										 |  |  |   /* configure output format? */ | 
					
						
							| 
									
										
										
										
											2008-03-29 12:24:36 +08:00
										 |  |  |   if (fop->format->get_options != NULL) { | 
					
						
							|  |  |  |     FormatOptions *format_options = (fop->format->get_options)(fop); | 
					
						
							| 
									
										
										
										
											2008-03-29 11:43:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* does the user cancelled the operation? */ | 
					
						
							| 
									
										
										
										
											2008-03-29 12:24:36 +08:00
										 |  |  |     if (format_options == NULL) { | 
					
						
							| 
									
										
										
										
											2008-03-29 11:43:19 +08:00
										 |  |  |       fop_free(fop); | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-29 12:24:36 +08:00
										 |  |  |     fop->seq.format_options = format_options; | 
					
						
							|  |  |  |     sprite_set_format_options(fop->sprite, | 
					
						
							|  |  |  | 			      format_options); | 
					
						
							| 
									
										
										
										
											2008-03-29 11:43:19 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   return fop; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Finally does the file operation: loading or saving the 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. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  |  * After operate you must to mark the 'fop' as 'done' using @ref fop_done. | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |  */ | 
					
						
							|  |  |  | void fop_operate(FileOp *fop) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   assert(fop != NULL); | 
					
						
							|  |  |  |   assert(!fop_is_done(fop)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* load ***********************************************************/ | 
					
						
							|  |  |  |   if (fop->type == FileOpLoad && | 
					
						
							|  |  |  |       fop->format != NULL && | 
					
						
							|  |  |  |       fop->format->load != NULL) { | 
					
						
							|  |  |  |     /* load a sequence */ | 
					
						
							|  |  |  |     if (fop->seq.filename_list != NULL) { | 
					
						
							|  |  |  |       int frame, frames, image_index = 0; | 
					
						
							|  |  |  |       Image *old_image; | 
					
						
							|  |  |  |       JLink link; | 
					
						
							|  |  |  |       bool loadres; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /* default palette */ | 
					
						
							| 
									
										
										
										
											2008-03-23 02:43:56 +08:00
										 |  |  |       palette_black(fop->seq.palette); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |        /* TODO set_palette for each frame??? */ | 
					
						
							|  |  |  | #define SEQUENCE_IMAGE()						\
 | 
					
						
							|  |  |  |       do {								\ | 
					
						
							|  |  |  | 	image_index = stock_add_image(fop->sprite->stock,		\ | 
					
						
							|  |  |  | 				      fop->seq.image);			\ | 
					
						
							|  |  |  | 									\ | 
					
						
							|  |  |  | 	fop->seq.last_cel->image = image_index;				\ | 
					
						
							| 
									
										
										
										
											2009-11-17 21:12:26 +08:00
										 |  |  | 	fop->seq.layer->add_cel(fop->seq.last_cel);			\ | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 									\ | 
					
						
							| 
									
										
										
										
											2008-03-23 02:43:56 +08:00
										 |  |  | 	if (palette_count_diff(sprite_get_palette(fop->sprite, frame),	\ | 
					
						
							|  |  |  | 			       fop->seq.palette, NULL, NULL) > 0) {	\ | 
					
						
							|  |  |  | 	  fop->seq.palette->frame = frame;				\ | 
					
						
							| 
									
										
										
										
											2010-01-31 00:43:13 +08:00
										 |  |  | 	  sprite_set_palette(fop->sprite, fop->seq.palette, true);	\ | 
					
						
							| 
									
										
										
										
											2008-03-23 02:43:56 +08:00
										 |  |  | 	}								\ | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 									\ | 
					
						
							|  |  |  | 	old_image = fop->seq.image;					\ | 
					
						
							|  |  |  | 	fop->seq.image = NULL;						\ | 
					
						
							|  |  |  | 	fop->seq.last_cel = NULL;					\ | 
					
						
							|  |  |  |       } while (0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /* load the sequence */ | 
					
						
							|  |  |  |       frames = jlist_length(fop->seq.filename_list); | 
					
						
							|  |  |  |       frame = 0; | 
					
						
							|  |  |  |       old_image = NULL; | 
					
						
							|  |  |  |        | 
					
						
							| 
									
										
										
										
											2010-01-31 00:43:13 +08:00
										 |  |  |       fop->seq.has_alpha = false; | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |       fop->seq.progress_offset = 0.0f; | 
					
						
							|  |  |  |       fop->seq.progress_fraction = 1.0f / (float)frames; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       JI_LIST_FOR_EACH(fop->seq.filename_list, link) { | 
					
						
							| 
									
										
										
										
											2008-10-01 05:01:54 +08:00
										 |  |  | 	fop->filename = reinterpret_cast<char*>(link->data); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* call the "load" procedure to read the first bitmap */ | 
					
						
							|  |  |  | 	loadres = (*fop->format->load)(fop); | 
					
						
							|  |  |  | 	if (!loadres) { | 
					
						
							|  |  |  | 	  fop_error(fop, _("Error loading frame %d from file \"%s\"\n"), | 
					
						
							|  |  |  | 		    frame+1, fop->filename); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 	/* for the first frame... */ | 
					
						
							|  |  |  | 	if (!old_image) { | 
					
						
							|  |  |  | 	  /* error reading the first frame */ | 
					
						
							|  |  |  | 	  if (!loadres || !fop->sprite || !fop->seq.last_cel) { | 
					
						
							|  |  |  | 	    if (fop->seq.image) image_free(fop->seq.image); | 
					
						
							|  |  |  | 	    if (fop->seq.last_cel) cel_free(fop->seq.last_cel); | 
					
						
							|  |  |  | 	    if (fop->sprite) { | 
					
						
							| 
									
										
										
										
											2009-06-01 10:59:15 +08:00
										 |  |  | 	      delete fop->sprite; | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 	      fop->sprite = NULL; | 
					
						
							|  |  |  | 	    } | 
					
						
							|  |  |  | 	    break; | 
					
						
							|  |  |  | 	  } | 
					
						
							|  |  |  | 	  /* read ok */ | 
					
						
							|  |  |  | 	  else { | 
					
						
							|  |  |  | 	    /* add the keyframe */ | 
					
						
							|  |  |  | 	    SEQUENCE_IMAGE(); | 
					
						
							|  |  |  | 	  } | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	/* for other frames */ | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 	  /* all done (or maybe not enough memory) */ | 
					
						
							|  |  |  | 	  if (!loadres || !fop->seq.last_cel) { | 
					
						
							|  |  |  | 	    if (fop->seq.image) image_free(fop->seq.image); | 
					
						
							|  |  |  | 	    if (fop->seq.last_cel) cel_free(fop->seq.last_cel); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 	    break; | 
					
						
							|  |  |  | 	  } | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 	  /* compare the old frame with the new one */ | 
					
						
							|  |  |  | #if USE_LINK /* TODO this should be configurable through a check-box */
 | 
					
						
							|  |  |  | 	  if (image_count_diff(old_image, fop->seq.image)) { | 
					
						
							|  |  |  | 	    SEQUENCE_IMAGE(); | 
					
						
							|  |  |  | 	  } | 
					
						
							|  |  |  | 	  /* we don't need this image */ | 
					
						
							|  |  |  | 	  else { | 
					
						
							|  |  |  | 	    image_free(fop->seq.image); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 	    /* but add a link frame */ | 
					
						
							|  |  |  | 	    fop->seq.last_cel->image = image_index; | 
					
						
							|  |  |  | 	    layer_add_frame(fop->seq.layer, fop->seq.last_cel); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 	    fop->seq.last_image = NULL; | 
					
						
							|  |  |  | 	    fop->seq.last_cel = NULL; | 
					
						
							|  |  |  | 	  } | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	  SEQUENCE_IMAGE(); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 	frame++; | 
					
						
							|  |  |  | 	fop->seq.progress_offset += fop->seq.progress_fraction; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2008-10-01 05:01:54 +08:00
										 |  |  |       fop->filename = jstrdup((char*)jlist_first_data(fop->seq.filename_list)); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-27 22:29:33 +08:00
										 |  |  |       /* final setup */ | 
					
						
							|  |  |  |       if (fop->sprite != NULL) { | 
					
						
							| 
									
										
										
										
											2008-03-29 11:43:19 +08:00
										 |  |  | 	/* configure the layer as the `Background' */ | 
					
						
							|  |  |  | 	if (!fop->seq.has_alpha) | 
					
						
							| 
									
										
										
										
											2009-11-17 21:12:26 +08:00
										 |  |  | 	  fop->seq.layer->configure_as_background(); | 
					
						
							| 
									
										
										
										
											2008-03-29 11:43:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-27 22:29:33 +08:00
										 |  |  | 	/* set the frames range */ | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 	sprite_set_frames(fop->sprite, frame); | 
					
						
							| 
									
										
										
										
											2008-03-27 22:29:33 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* set the frames range */ | 
					
						
							| 
									
										
										
										
											2008-03-29 12:24:36 +08:00
										 |  |  | 	sprite_set_format_options(fop->sprite, | 
					
						
							|  |  |  | 				  fop->seq.format_options); | 
					
						
							| 
									
										
										
										
											2008-03-27 22:29:33 +08:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-03-27 22:29:33 +08:00
										 |  |  |     /* direct load from one file */ | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |     else { | 
					
						
							|  |  |  |       /* call the "load" procedure */ | 
					
						
							|  |  |  |       if (!(*fop->format->load)(fop)) | 
					
						
							|  |  |  | 	fop_error(fop, _("Error loading sprite from file \"%s\"\n"), | 
					
						
							|  |  |  | 		  fop->filename); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (fop->sprite != NULL) { | 
					
						
							|  |  |  |       /* select the last layer */ | 
					
						
							| 
									
										
										
										
											2009-11-17 21:12:26 +08:00
										 |  |  |       if (fop->sprite->get_folder()->get_layers_count() > 0) { | 
					
						
							|  |  |  | 	LayerIterator last_layer = --fop->sprite->get_folder()->get_layer_end(); | 
					
						
							|  |  |  | 	sprite_set_layer(fop->sprite, *last_layer); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       /* set the filename */ | 
					
						
							|  |  |  |       if (fop->seq.filename_list) | 
					
						
							|  |  |  | 	sprite_set_filename(fop->sprite, | 
					
						
							| 
									
										
										
										
											2008-10-01 05:01:54 +08:00
										 |  |  | 			    reinterpret_cast<char*>(jlist_first_data(fop->seq.filename_list))); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |       else | 
					
						
							|  |  |  | 	sprite_set_filename(fop->sprite, fop->filename); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       sprite_mark_as_saved(fop->sprite); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* save ***********************************************************/ | 
					
						
							|  |  |  |   else if (fop->type == FileOpSave && | 
					
						
							|  |  |  | 	   fop->format != NULL && | 
					
						
							|  |  |  | 	   fop->format->save != NULL) { | 
					
						
							|  |  |  |     /* save a sequence */ | 
					
						
							|  |  |  |     if (fop->seq.filename_list != NULL) { | 
					
						
							|  |  |  |       assert(fop->format->flags & FILE_SUPPORT_SEQUENCES); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /* create a temporary bitmap */ | 
					
						
							|  |  |  |       fop->seq.image = image_new(fop->sprite->imgtype, | 
					
						
							|  |  |  | 				 fop->sprite->w, | 
					
						
							|  |  |  | 				 fop->sprite->h); | 
					
						
							|  |  |  |       if (fop->seq.image != NULL) { | 
					
						
							|  |  |  | 	int old_frame = fop->sprite->frame; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fop->seq.progress_offset = 0.0f; | 
					
						
							|  |  |  | 	fop->seq.progress_fraction = 1.0f / (float)fop->sprite->frames; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* for each frame in the sprite */ | 
					
						
							|  |  |  | 	for (fop->sprite->frame=0; | 
					
						
							|  |  |  | 	     fop->sprite->frame<fop->sprite->frames; | 
					
						
							|  |  |  | 	     fop->sprite->frame++) { | 
					
						
							|  |  |  | 	  /* draw all the sprite in this frame in the image */ | 
					
						
							|  |  |  | 	  image_clear(fop->seq.image, 0); | 
					
						
							|  |  |  | 	  sprite_render(fop->sprite, fop->seq.image, 0, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	  /* setup the palette */ | 
					
						
							| 
									
										
										
										
											2008-03-23 02:43:56 +08:00
										 |  |  | 	  palette_copy_colors(fop->seq.palette, | 
					
						
							|  |  |  | 			      sprite_get_palette(fop->sprite, | 
					
						
							|  |  |  | 						 fop->sprite->frame)); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	  /* setup the filename to be used */ | 
					
						
							| 
									
										
										
										
											2008-10-01 05:01:54 +08:00
										 |  |  | 	  fop->filename = reinterpret_cast<char*> | 
					
						
							|  |  |  | 	    (jlist_nth_data(fop->seq.filename_list, | 
					
						
							|  |  |  | 			    fop->sprite->frame)); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	  /* call the "save" procedure... did it fail? */ | 
					
						
							|  |  |  | 	  if (!(*fop->format->save)(fop)) { | 
					
						
							|  |  |  | 	    fop_error(fop, _("Error saving frame %d in the file \"%s\"\n"), | 
					
						
							|  |  |  | 		      fop->sprite->frame+1, fop->filename); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 	    break; | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 	  } | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 	  fop->seq.progress_offset += fop->seq.progress_fraction; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-10-01 05:01:54 +08:00
										 |  |  | 	fop->filename = jstrdup(reinterpret_cast<char*>(jlist_first_data(fop->seq.filename_list))); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 	/* destroy the image */ | 
					
						
							|  |  |  | 	image_free(fop->seq.image); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 	/* restore frame */ | 
					
						
							|  |  |  | 	fop->sprite->frame = old_frame; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  | 	fop_error(fop, _("Not enough memory for the temporary bitmap.\n")); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |     /* direct save to a file */ | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |     else { | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |       /* call the "save" procedure */ | 
					
						
							|  |  |  |       if (!(*fop->format->save)(fop)) | 
					
						
							|  |  |  | 	fop_error(fop, _("Error saving the sprite in the file \"%s\"\n"), | 
					
						
							|  |  |  | 		  fop->filename); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  |   /* 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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   /* finally done */ | 
					
						
							|  |  |  |   jmutex_lock(fop->mutex); | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2010-01-31 00:43:13 +08:00
										 |  |  |     fop->done = true; | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   } | 
					
						
							|  |  |  |   jmutex_unlock(fop->mutex); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  | void fop_stop(FileOp *fop) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   jmutex_lock(fop->mutex); | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     if (!fop->done) | 
					
						
							| 
									
										
										
										
											2010-01-31 00:43:13 +08:00
										 |  |  |       fop->stop = true; | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  |   } | 
					
						
							|  |  |  |   jmutex_unlock(fop->mutex); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | void fop_free(FileOp *fop) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if (fop->filename) | 
					
						
							|  |  |  |     jfree(fop->filename); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   if (fop->error) | 
					
						
							|  |  |  |     jfree(fop->error); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (fop->seq.filename_list) { | 
					
						
							|  |  |  |     JLink link; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* free old filenames strings */ | 
					
						
							|  |  |  |     JI_LIST_FOR_EACH(fop->seq.filename_list, link) | 
					
						
							|  |  |  |       jfree(link->data); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     jlist_free(fop->seq.filename_list); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-23 02:43:56 +08:00
										 |  |  |   if (fop->seq.palette != NULL) | 
					
						
							|  |  |  |     palette_free(fop->seq.palette); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-01 04:15:38 +08:00
										 |  |  |   if (fop->mutex) | 
					
						
							|  |  |  |     jmutex_free(fop->mutex); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   jfree(fop); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-29 12:24:36 +08:00
										 |  |  | void fop_sequence_set_format_options(FileOp *fop, FormatOptions *format_options) | 
					
						
							| 
									
										
										
										
											2008-03-27 22:29:33 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-03-29 12:24:36 +08:00
										 |  |  |   assert(fop->seq.format_options == NULL); | 
					
						
							|  |  |  |   fop->seq.format_options = format_options; | 
					
						
							| 
									
										
										
										
											2008-03-27 22:29:33 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | void fop_sequence_set_color(FileOp *fop, int index, int r, int g, int b) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2008-03-23 02:43:56 +08:00
										 |  |  |   palette_set_entry(fop->seq.palette, index, _rgba(r, g, b, 255)); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void fop_sequence_get_color(FileOp *fop, int index, int *r, int *g, int *b) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2008-03-23 02:43:56 +08:00
										 |  |  |   ase_uint32 c = palette_get_entry(fop->seq.palette, index); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-23 02:43:56 +08:00
										 |  |  |   *r = _rgba_getr(c); | 
					
						
							|  |  |  |   *g = _rgba_getg(c); | 
					
						
							|  |  |  |   *b = _rgba_getb(c); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Image *fop_sequence_image(FileOp *fop, int imgtype, int w, int h) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-17 21:12:26 +08:00
										 |  |  |   Sprite* sprite; | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* create the image */ | 
					
						
							|  |  |  |   if (!fop->sprite) { | 
					
						
							|  |  |  |     sprite = sprite_new(imgtype, w, h); | 
					
						
							| 
									
										
										
										
											2009-11-17 21:12:26 +08:00
										 |  |  |     try { | 
					
						
							|  |  |  |       LayerImage* layer = new LayerImage(sprite); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /* add the layer */ | 
					
						
							|  |  |  |       sprite->get_folder()->add_layer(layer); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-17 21:12:26 +08:00
										 |  |  |       /* done */ | 
					
						
							|  |  |  |       fop->sprite = sprite; | 
					
						
							|  |  |  |       fop->seq.layer = layer; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     catch (...) { | 
					
						
							| 
									
										
										
										
											2009-06-01 10:59:15 +08:00
										 |  |  |       delete sprite; | 
					
						
							| 
									
										
										
										
											2009-11-17 21:12:26 +08:00
										 |  |  |       throw; | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |     sprite = fop->sprite; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (sprite->imgtype != imgtype) | 
					
						
							|  |  |  |       return NULL; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   /* create a bitmap */ | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   if (fop->seq.last_cel) { | 
					
						
							|  |  |  |     fop_error(fop, _("Error: called two times \"fop_sequence_image()\".\n")); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-17 21:12:26 +08:00
										 |  |  |   Image* image = image_new(imgtype, w, h); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   if (!image) { | 
					
						
							|  |  |  |     fop_error(fop, _("Not enough memory to allocate a bitmap.\n")); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   fop->seq.image = image; | 
					
						
							|  |  |  |   fop->seq.last_cel = cel_new(fop->seq.frame++, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return image; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void fop_error(FileOp *fop, const char *format, ...) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   char buf_error[4096]; | 
					
						
							|  |  |  |   va_list ap; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   va_start(ap, format); | 
					
						
							|  |  |  |   uvszprintf(buf_error, sizeof(buf_error), format, ap); | 
					
						
							|  |  |  |   va_end(ap); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   jmutex_lock(fop->mutex); | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     /* concatenate old errors with the new one */ | 
					
						
							|  |  |  |     if (fop->error) { | 
					
						
							|  |  |  |       char *old_error = fop->error; | 
					
						
							| 
									
										
										
										
											2008-10-01 05:01:54 +08:00
										 |  |  |       fop->error = reinterpret_cast<char*>(jmalloc(ustrsizez(old_error) + ustrsizez(buf_error) + 1)); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |       ustrcpy(fop->error, old_error); | 
					
						
							|  |  |  |       ustrcat(fop->error, buf_error); | 
					
						
							|  |  |  |       jfree(old_error); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     /* first error */ | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       fop->error = jstrdup(buf_error); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   jmutex_unlock(fop->mutex); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void fop_progress(FileOp *fop, float progress) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   /* rest(8); */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   jmutex_lock(fop->mutex); | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     if (fop->seq.filename_list != NULL) { | 
					
						
							|  |  |  |       fop->progress = | 
					
						
							|  |  |  | 	fop->seq.progress_offset + | 
					
						
							|  |  |  | 	fop->seq.progress_fraction*progress; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       fop->progress = progress; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   jmutex_unlock(fop->mutex); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | float fop_get_progress(FileOp *fop) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   float progress; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   jmutex_lock(fop->mutex); | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     progress = fop->progress; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   jmutex_unlock(fop->mutex); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return progress; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Returns true when the file operation finished, this means, when the | 
					
						
							|  |  |  |  * 'fop_operate()' routine ends. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | bool fop_is_done(FileOp *fop) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   bool done; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   jmutex_lock(fop->mutex); | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     done = fop->done; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   jmutex_unlock(fop->mutex); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return done; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool fop_is_stop(FileOp *fop) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   bool stop; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   jmutex_lock(fop->mutex); | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     stop = fop->stop; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   jmutex_unlock(fop->mutex); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return stop; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static FileOp *fop_new(FileOpType type) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   FileOp *fop = jnew(FileOp, 1); | 
					
						
							|  |  |  |   if (!fop) | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   fop->type = type; | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  |   fop->format = NULL; | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   fop->sprite = NULL; | 
					
						
							|  |  |  |   fop->filename = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   fop->mutex = jmutex_new(); | 
					
						
							|  |  |  |   fop->progress = 0.0f; | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  |   fop->error = NULL; | 
					
						
							| 
									
										
										
										
											2010-01-31 00:43:13 +08:00
										 |  |  |   fop->done = false; | 
					
						
							|  |  |  |   fop->stop = false; | 
					
						
							|  |  |  |   fop->oneframe = false; | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   fop->seq.filename_list = NULL; | 
					
						
							|  |  |  |   fop->seq.palette = NULL; | 
					
						
							|  |  |  |   fop->seq.image = NULL; | 
					
						
							|  |  |  |   fop->seq.progress_offset = 0.0f; | 
					
						
							|  |  |  |   fop->seq.progress_fraction = 0.0f; | 
					
						
							|  |  |  |   fop->seq.frame = 0; | 
					
						
							|  |  |  |   fop->seq.layer = NULL; | 
					
						
							|  |  |  |   fop->seq.last_cel = NULL; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   return fop; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void fop_prepare_for_sequence(FileOp *fop) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   fop->seq.filename_list = jlist_new(); | 
					
						
							| 
									
										
										
										
											2008-03-23 02:43:56 +08:00
										 |  |  |   fop->seq.palette = palette_new(0, MAX_PALETTE_COLORS); | 
					
						
							| 
									
										
										
										
											2008-03-29 12:24:36 +08:00
										 |  |  |   fop->seq.format_options = NULL; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-05 09:30:50 +08:00
										 |  |  | static FileFormat *get_fileformat(const char *extension) | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | { | 
					
						
							|  |  |  |   char buf[512], *tok; | 
					
						
							|  |  |  |   int c; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-05 09:30:50 +08:00
										 |  |  |   for (c=0; formats[c]; c++) { | 
					
						
							|  |  |  |     ustrcpy(buf, formats[c]->exts); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-05 09:30:50 +08:00
										 |  |  |     for (tok=ustrtok(buf, ","); tok; | 
					
						
							|  |  |  | 	 tok=ustrtok(NULL, ",")) { | 
					
						
							|  |  |  |       if (ustricmp(extension, tok) == 0) | 
					
						
							|  |  |  | 	return formats[c]; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* splits a file-name like "my_ani0000.pcx" to "my_ani" and ".pcx",
 | 
					
						
							|  |  |  |    returning the number of the center; returns "-1" if the function | 
					
						
							|  |  |  |    can't split anything */ | 
					
						
							|  |  |  | static int split_filename(const char *filename, char *left, char *right, int *width) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   char *ptr, *ext; | 
					
						
							|  |  |  |   char buf[16]; | 
					
						
							|  |  |  |   int chr, ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* get the extension */ | 
					
						
							| 
									
										
										
										
											2008-01-07 23:10:17 +08:00
										 |  |  |   ext = get_extension(filename); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* with extension */ | 
					
						
							|  |  |  |   if ((ext) && (*ext)) { | 
					
						
							|  |  |  |     /* left side (the filename without the extension and without the '.') */ | 
					
						
							|  |  |  |     ext--; | 
					
						
							|  |  |  |     *ext = 0; | 
					
						
							| 
									
										
										
										
											2008-01-07 23:10:17 +08:00
										 |  |  |     ustrcpy(left, filename); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |     *ext = '.'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* right side (the extension with the '.') */ | 
					
						
							| 
									
										
										
										
											2008-01-07 23:10:17 +08:00
										 |  |  |     ustrcpy(right, ext); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   } | 
					
						
							|  |  |  |   /* without extension (without right side) */ | 
					
						
							|  |  |  |   else { | 
					
						
							| 
									
										
										
										
											2008-01-07 23:10:17 +08:00
										 |  |  |     ustrcpy(left, filename); | 
					
						
							|  |  |  |     ustrcpy(right, empty_string); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* remove all trailing numbers in the "left" side, and pass they to "buf" */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ptr = buf+9; | 
					
						
							|  |  |  |   ptr[1] = 0; | 
					
						
							|  |  |  |   ret = -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (width) | 
					
						
							|  |  |  |     *width = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (;;) { | 
					
						
							| 
									
										
										
										
											2008-01-07 23:10:17 +08:00
										 |  |  |     chr = ugetat(left, -1); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |     if ((chr >= '0') && (chr <= '9')) { | 
					
						
							|  |  |  |       ret = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (ptr >= buf) { | 
					
						
							|  |  |  | 	*(ptr--) = chr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (width) | 
					
						
							|  |  |  | 	  (*width)++; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       uremove(left, -1); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* convert the "buf" to integer and return it */ | 
					
						
							|  |  |  |   if (ret == 0) { | 
					
						
							|  |  |  |     while (ptr >= buf) | 
					
						
							|  |  |  |       *(ptr--) = '0'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-05 09:30:50 +08:00
										 |  |  |     ret = ustrtol(buf, NULL, 10); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ret; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * 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; | 
					
						
							|  |  |  | } |