| 
									
										
										
										
											2015-02-12 23:16:25 +08:00
										 |  |  | // Aseprite
 | 
					
						
							| 
									
										
										
										
											2018-02-08 04:25:58 +08:00
										 |  |  | // Copyright (C) 2001-2018  David Capello
 | 
					
						
							| 
									
										
										
										
											2015-02-12 23:16:25 +08:00
										 |  |  | //
 | 
					
						
							| 
									
										
										
										
											2016-08-27 04:02:58 +08:00
										 |  |  | // This program is distributed under the terms of
 | 
					
						
							|  |  |  | // the End-User License Agreement for Aseprite.
 | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-06 08:20:19 +08:00
										 |  |  | #ifdef HAVE_CONFIG_H
 | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | #include "config.h"
 | 
					
						
							| 
									
										
										
										
											2013-08-06 08:20:19 +08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-15 06:58:11 +08:00
										 |  |  | #include "app/file/file.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-06 08:20:19 +08:00
										 |  |  | #include "app/console.h"
 | 
					
						
							| 
									
										
										
										
											2014-07-20 09:01:39 +08:00
										 |  |  | #include "app/context.h"
 | 
					
						
							| 
									
										
										
										
											2018-07-07 22:54:44 +08:00
										 |  |  | #include "app/doc.h"
 | 
					
						
							| 
									
										
										
										
											2017-04-12 23:35:13 +08:00
										 |  |  | #include "app/file/file_data.h"
 | 
					
						
							| 
									
										
										
										
											2013-08-06 08:20:19 +08:00
										 |  |  | #include "app/file/file_format.h"
 | 
					
						
							|  |  |  | #include "app/file/file_formats_manager.h"
 | 
					
						
							|  |  |  | #include "app/file/format_options.h"
 | 
					
						
							| 
									
										
										
										
											2014-09-22 00:42:46 +08:00
										 |  |  | #include "app/file/split_filename.h"
 | 
					
						
							| 
									
										
										
										
											2015-01-26 09:36:32 +08:00
										 |  |  | #include "app/filename_formatter.h"
 | 
					
						
							| 
									
										
										
										
											2017-10-18 05:00:45 +08:00
										 |  |  | #include "app/i18n/strings.h"
 | 
					
						
							| 
									
										
										
										
											2013-08-06 08:20:19 +08:00
										 |  |  | #include "app/modules/gui.h"
 | 
					
						
							|  |  |  | #include "app/modules/palettes.h"
 | 
					
						
							| 
									
										
										
										
											2018-02-08 04:25:58 +08:00
										 |  |  | #include "app/pref/preferences.h"
 | 
					
						
							|  |  |  | #include "app/ui/optional_alert.h"
 | 
					
						
							| 
									
										
										
										
											2013-10-15 06:58:11 +08:00
										 |  |  | #include "app/ui/status_bar.h"
 | 
					
						
							|  |  |  | #include "base/fs.h"
 | 
					
						
							|  |  |  | #include "base/mutex.h"
 | 
					
						
							|  |  |  | #include "base/scoped_lock.h"
 | 
					
						
							|  |  |  | #include "base/shared_ptr.h"
 | 
					
						
							|  |  |  | #include "base/string.h"
 | 
					
						
							| 
									
										
										
										
											2017-09-23 02:57:38 +08:00
										 |  |  | #include "dio/detect_format.h"
 | 
					
						
							| 
									
										
										
										
											2014-10-21 09:21:31 +08:00
										 |  |  | #include "doc/doc.h"
 | 
					
						
							| 
									
										
										
										
											2017-10-18 05:00:45 +08:00
										 |  |  | #include "fmt/format.h"
 | 
					
						
							| 
									
										
										
										
											2014-12-28 22:06:11 +08:00
										 |  |  | #include "render/quantization.h"
 | 
					
						
							|  |  |  | #include "render/render.h"
 | 
					
						
							| 
									
										
										
										
											2018-06-09 02:52:10 +08:00
										 |  |  | #include "ui/listitem.h"
 | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-16 05:11:47 +08:00
										 |  |  | #include "open_sequence.xml.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-15 06:58:11 +08:00
										 |  |  | #include <cstring>
 | 
					
						
							| 
									
										
										
										
											2015-02-12 21:55:58 +08:00
										 |  |  | #include <cstdarg>
 | 
					
						
							| 
									
										
										
										
											2011-03-23 08:11:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-06 08:20:19 +08:00
										 |  |  | namespace app { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | using namespace base; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-21 21:39:30 +08:00
										 |  |  | base::paths get_readable_extensions() | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-21 21:39:30 +08:00
										 |  |  |   base::paths paths; | 
					
						
							| 
									
										
										
										
											2015-03-18 04:17:01 +08:00
										 |  |  |   for (const FileFormat* format : *FileFormatsManager::instance()) { | 
					
						
							| 
									
										
										
										
											2018-02-21 21:39:30 +08:00
										 |  |  |     if (format->support(FILE_SUPPORT_LOAD)) | 
					
						
							|  |  |  |       format->getExtensions(paths); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-02-21 21:39:30 +08:00
										 |  |  |   return paths; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-21 21:39:30 +08:00
										 |  |  | base::paths get_writable_extensions() | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-21 21:39:30 +08:00
										 |  |  |   base::paths paths; | 
					
						
							| 
									
										
										
										
											2015-03-18 04:17:01 +08:00
										 |  |  |   for (const FileFormat* format : *FileFormatsManager::instance()) { | 
					
						
							| 
									
										
										
										
											2018-02-21 21:39:30 +08:00
										 |  |  |     if (format->support(FILE_SUPPORT_SAVE)) | 
					
						
							|  |  |  |       format->getExtensions(paths); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-02-21 21:39:30 +08:00
										 |  |  |   return paths; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-07 22:54:44 +08:00
										 |  |  | Doc* load_document(Context* context, const std::string& filename) | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  |   /* TODO add a option to configure what to do with the sequence */ | 
					
						
							| 
									
										
										
										
											2018-08-09 04:27:26 +08:00
										 |  |  |   std::unique_ptr<FileOp> fop(FileOp::createLoadDocumentOperation(context, filename, FILE_LOAD_SEQUENCE_NONE)); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   if (!fop) | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |     return nullptr; | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   // Operate in this same thread
 | 
					
						
							|  |  |  |   fop->operate(); | 
					
						
							|  |  |  |   fop->done(); | 
					
						
							|  |  |  |   fop->postLoad(); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   if (fop->hasError()) { | 
					
						
							| 
									
										
										
										
											2015-04-06 22:58:42 +08:00
										 |  |  |     Console console(context); | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |     console.printf(fop->error().c_str()); | 
					
						
							| 
									
										
										
										
											2009-06-11 23:11:11 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-07 22:54:44 +08:00
										 |  |  |   Doc* document = fop->releaseDocument(); | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   fop.release(); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 20:46:25 +08:00
										 |  |  |   if (document && context) | 
					
						
							| 
									
										
										
										
											2014-07-29 11:53:24 +08:00
										 |  |  |     document->setContext(context); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-23 08:11:25 +08:00
										 |  |  |   return document; | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-07 22:54:44 +08:00
										 |  |  | int save_document(Context* context, Doc* document) | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-08-09 04:27:26 +08:00
										 |  |  |   std::unique_ptr<FileOp> fop( | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |     FileOp::createSaveDocumentOperation( | 
					
						
							|  |  |  |       context, | 
					
						
							| 
									
										
										
										
											2018-07-07 22:54:44 +08:00
										 |  |  |       FileOpROI(document, "", "", SelectedFrames(), false), | 
					
						
							| 
									
										
										
										
											2017-03-16 10:53:29 +08:00
										 |  |  |       document->filename(), "")); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   if (!fop) | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   // Operate in this same thread
 | 
					
						
							|  |  |  |   fop->operate(); | 
					
						
							|  |  |  |   fop->done(); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   if (fop->hasError()) { | 
					
						
							| 
									
										
										
										
											2015-04-06 22:58:42 +08:00
										 |  |  |     Console console(context); | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |     console.printf(fop->error().c_str()); | 
					
						
							| 
									
										
										
										
											2009-06-11 23:11:11 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   return (!fop->hasError() ? 0: -1); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-07 00:57:35 +08:00
										 |  |  | bool is_static_image_format(const std::string& filename) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   // Get the format through the extension of the filename
 | 
					
						
							| 
									
										
										
										
											2016-10-27 23:51:06 +08:00
										 |  |  |   FileFormat* format = | 
					
						
							|  |  |  |     FileFormatsManager::instance() | 
					
						
							| 
									
										
										
										
											2017-09-23 02:57:38 +08:00
										 |  |  |     ->getFileFormat(dio::detect_format_by_file_extension(filename)); | 
					
						
							| 
									
										
										
										
											2016-06-07 00:57:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return (format && format->support(FILE_SUPPORT_SEQUENCES)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-07 04:47:47 +08:00
										 |  |  | FileOpROI::FileOpROI() | 
					
						
							|  |  |  |   : m_document(nullptr) | 
					
						
							| 
									
										
										
										
											2017-04-12 05:45:51 +08:00
										 |  |  |   , m_slice(nullptr) | 
					
						
							| 
									
										
										
										
											2016-06-07 04:47:47 +08:00
										 |  |  |   , m_frameTag(nullptr) | 
					
						
							| 
									
										
										
										
											2016-06-02 01:49:24 +08:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-07 22:54:44 +08:00
										 |  |  | FileOpROI::FileOpROI(const Doc* doc, | 
					
						
							| 
									
										
										
										
											2017-04-12 05:45:51 +08:00
										 |  |  |                      const std::string& sliceName, | 
					
						
							| 
									
										
										
										
											2016-06-07 04:47:47 +08:00
										 |  |  |                      const std::string& frameTagName, | 
					
						
							| 
									
										
										
										
											2016-09-19 23:39:53 +08:00
										 |  |  |                      const doc::SelectedFrames& selFrames, | 
					
						
							| 
									
										
										
										
											2016-09-17 12:01:28 +08:00
										 |  |  |                      const bool adjustByFrameTag) | 
					
						
							| 
									
										
										
										
											2016-06-02 01:49:24 +08:00
										 |  |  |   : m_document(doc) | 
					
						
							| 
									
										
										
										
											2017-04-12 05:45:51 +08:00
										 |  |  |   , m_slice(nullptr) | 
					
						
							| 
									
										
										
										
											2016-06-02 01:49:24 +08:00
										 |  |  |   , m_frameTag(nullptr) | 
					
						
							| 
									
										
										
										
											2016-09-17 12:01:28 +08:00
										 |  |  |   , m_selFrames(selFrames) | 
					
						
							| 
									
										
										
										
											2016-06-02 01:49:24 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-07 04:47:47 +08:00
										 |  |  |   if (doc) { | 
					
						
							| 
									
										
										
										
											2017-04-12 05:45:51 +08:00
										 |  |  |     if (!sliceName.empty()) | 
					
						
							|  |  |  |       m_slice = doc->sprite()->slices().getByName(sliceName); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-15 04:03:25 +08:00
										 |  |  |     // Don't allow exporting frame tags with empty names
 | 
					
						
							|  |  |  |     if (!frameTagName.empty()) | 
					
						
							|  |  |  |       m_frameTag = doc->sprite()->frameTags().getByName(frameTagName); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-17 12:01:28 +08:00
										 |  |  |     if (m_frameTag) { | 
					
						
							| 
									
										
										
										
											2016-09-19 23:39:53 +08:00
										 |  |  |       if (m_selFrames.empty()) | 
					
						
							|  |  |  |         m_selFrames.insert(m_frameTag->fromFrame(), m_frameTag->toFrame()); | 
					
						
							|  |  |  |       else if (adjustByFrameTag) | 
					
						
							| 
									
										
										
										
											2016-09-17 12:01:28 +08:00
										 |  |  |         m_selFrames.displace(m_frameTag->fromFrame()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-16 19:59:34 +08:00
										 |  |  |       m_selFrames = | 
					
						
							|  |  |  |         m_selFrames.filter(MAX(0, m_frameTag->fromFrame()), | 
					
						
							|  |  |  |                            MIN(m_frameTag->toFrame(), doc->sprite()->lastFrame())); | 
					
						
							| 
									
										
										
										
											2016-06-07 04:47:47 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-09-17 12:01:28 +08:00
										 |  |  |     // All frames if selected frames is empty
 | 
					
						
							|  |  |  |     else if (m_selFrames.empty()) | 
					
						
							|  |  |  |       m_selFrames.insert(0, doc->sprite()->lastFrame()); | 
					
						
							| 
									
										
										
										
											2016-06-07 04:47:47 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-06-02 01:49:24 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  | // static
 | 
					
						
							| 
									
										
										
										
											2017-03-16 10:53:29 +08:00
										 |  |  | FileOp* FileOp::createLoadDocumentOperation(Context* context, const std::string& filename, int flags) | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-08-09 04:27:26 +08:00
										 |  |  |   std::unique_ptr<FileOp> fop( | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |     new FileOp(FileOpLoad, context)); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   if (!fop) | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |     return nullptr; | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-16 10:53:29 +08:00
										 |  |  |   LOG("FILE: Loading file \"%s\"\n", filename.c_str()); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-15 06:58:11 +08:00
										 |  |  |   // Does file exist?
 | 
					
						
							| 
									
										
										
										
											2014-04-18 04:12:55 +08:00
										 |  |  |   if (!base::is_file(filename)) { | 
					
						
							| 
									
										
										
										
											2017-03-16 10:53:29 +08:00
										 |  |  |     fop->setError("File not found: \"%s\"\n", filename.c_str()); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |     goto done; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 10:39:20 +08:00
										 |  |  |   // Get the format through the extension of the filename
 | 
					
						
							| 
									
										
										
										
											2016-10-27 06:37:42 +08:00
										 |  |  |   fop->m_format = FileFormatsManager::instance()->getFileFormat( | 
					
						
							| 
									
										
										
										
											2017-09-23 02:57:38 +08:00
										 |  |  |     dio::detect_format(filename)); | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   if (!fop->m_format || | 
					
						
							|  |  |  |       !fop->m_format->support(FILE_SUPPORT_LOAD)) { | 
					
						
							| 
									
										
										
										
											2016-10-27 06:37:42 +08:00
										 |  |  |     fop->setError("%s can't load \"%s\" file (\"%s\")\n", PACKAGE, | 
					
						
							| 
									
										
										
										
											2017-03-16 10:53:29 +08:00
										 |  |  |                   filename.c_str(), base::get_file_extension(filename).c_str()); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |     goto done; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-25 02:37:01 +08:00
										 |  |  |   // Use the "sequence" interface
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   if (fop->m_format->support(FILE_SUPPORT_SEQUENCES)) { | 
					
						
							|  |  |  |     fop->prepareForSequence(); | 
					
						
							| 
									
										
										
										
											2016-11-16 05:11:47 +08:00
										 |  |  |     fop->m_seq.flags = flags; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-25 02:37:01 +08:00
										 |  |  |     // At the moment we want load just one file (the one specified in filename)
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |     fop->m_seq.filename_list.push_back(filename); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-25 02:37:01 +08:00
										 |  |  |     // If the user wants to load the whole sequence
 | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  |     if (!(flags & FILE_LOAD_SEQUENCE_NONE)) { | 
					
						
							| 
									
										
										
										
											2014-09-22 00:42:46 +08:00
										 |  |  |       std::string left, right; | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  |       int c, width, start_from; | 
					
						
							| 
									
										
										
										
											2014-09-22 00:42:46 +08:00
										 |  |  |       char buf[512]; | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-07 00:57:35 +08:00
										 |  |  |       // First of all, we must generate the list of files to load in the
 | 
					
						
							|  |  |  |       // sequence...
 | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-22 00:42:46 +08:00
										 |  |  |       // Check is this could be a sequence
 | 
					
						
							|  |  |  |       start_from = split_filename(filename, left, right, width); | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  |       if (start_from >= 0) { | 
					
						
							| 
									
										
										
										
											2014-09-22 00:42:46 +08:00
										 |  |  |         // Try to get more file names
 | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |         for (c=start_from+1; ; c++) { | 
					
						
							| 
									
										
										
										
											2014-09-22 00:42:46 +08:00
										 |  |  |           // Get the next file name
 | 
					
						
							|  |  |  |           sprintf(buf, "%s%0*d%s", left.c_str(), width, c, right.c_str()); | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-22 00:42:46 +08:00
										 |  |  |           // If the file doesn't exist, we doesn't need more files to load
 | 
					
						
							|  |  |  |           if (!base::is_file(buf)) | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |             break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           /* add this file name to the list */ | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |           fop->m_seq.filename_list.push_back(buf); | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-07 11:11:50 +08:00
										 |  |  | #ifdef ENABLE_UI
 | 
					
						
							| 
									
										
										
										
											2016-11-16 05:11:47 +08:00
										 |  |  |       // TODO add a better dialog to edit file-names
 | 
					
						
							|  |  |  |       if ((flags & FILE_LOAD_SEQUENCE_ASK) && | 
					
						
							|  |  |  |           context && | 
					
						
							|  |  |  |           context->isUIAvailable() && | 
					
						
							|  |  |  |           fop->m_seq.filename_list.size() > 1) { | 
					
						
							|  |  |  |         app::gen::OpenSequence window; | 
					
						
							|  |  |  |         window.repeat()->setVisible(flags & FILE_LOAD_SEQUENCE_ASK_CHECKBOX ? true: false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (const auto& fn : fop->m_seq.filename_list) { | 
					
						
							|  |  |  |           auto item = new ui::ListItem(base::get_file_name(fn)); | 
					
						
							|  |  |  |           item->setSelected(true); | 
					
						
							|  |  |  |           window.files()->addChild(item); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         window.files()->Change.connect( | 
					
						
							|  |  |  |           [&window]{ | 
					
						
							|  |  |  |             window.agree()->setEnabled( | 
					
						
							|  |  |  |               window.files()->getSelectedChild() != nullptr); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         window.openWindowInForeground(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // If the user selected the "do the same for other files"
 | 
					
						
							|  |  |  |         // checkbox, we've to save what the user want to do for the
 | 
					
						
							|  |  |  |         // following files.
 | 
					
						
							|  |  |  |         if (window.repeat()->isSelected()) { | 
					
						
							|  |  |  |           if (window.closer() == window.agree()) | 
					
						
							|  |  |  |             fop->m_seq.flags = FILE_LOAD_SEQUENCE_YES; | 
					
						
							|  |  |  |           else | 
					
						
							|  |  |  |             fop->m_seq.flags = FILE_LOAD_SEQUENCE_NONE; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (window.closer() == window.agree()) { | 
					
						
							|  |  |  |           // If the user replies "Agree", we load the selected files.
 | 
					
						
							| 
									
										
										
										
											2018-02-21 21:39:30 +08:00
										 |  |  |           base::paths list; | 
					
						
							| 
									
										
										
										
											2016-11-16 05:11:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |           auto it = window.files()->children().begin(); | 
					
						
							|  |  |  |           auto end = window.files()->children().end(); | 
					
						
							|  |  |  |           for (const auto& fn : fop->m_seq.filename_list) { | 
					
						
							|  |  |  |             ASSERT(it != end); | 
					
						
							|  |  |  |             if (it == end) | 
					
						
							|  |  |  |               break; | 
					
						
							|  |  |  |             if ((*it)->isSelected()) | 
					
						
							|  |  |  |               list.push_back(fn); | 
					
						
							|  |  |  |             ++it; | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2014-09-22 00:42:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-16 05:11:47 +08:00
										 |  |  |           ASSERT(!list.empty()); | 
					
						
							|  |  |  |           fop->m_seq.filename_list = list; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							| 
									
										
										
										
											2014-09-22 00:42:46 +08:00
										 |  |  |           // If the user replies "Skip", we need just one file name
 | 
					
						
							|  |  |  |           // (the first one).
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |           if (fop->m_seq.filename_list.size() > 1) { | 
					
						
							|  |  |  |             fop->m_seq.filename_list.erase(fop->m_seq.filename_list.begin()+1, | 
					
						
							|  |  |  |                                            fop->m_seq.filename_list.end()); | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2018-05-07 11:11:50 +08:00
										 |  |  | #endif // ENABLE_UI
 | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-03-07 06:27:43 +08:00
										 |  |  |   else { | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |     fop->m_filename = filename; | 
					
						
							| 
									
										
										
										
											2017-03-07 06:27:43 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-07 06:27:43 +08:00
										 |  |  |   // Load just one frame
 | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  |   if (flags & FILE_LOAD_ONE_FRAME) | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |     fop->m_oneframe = true; | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-07 06:27:43 +08:00
										 |  |  |   // Does data file exist?
 | 
					
						
							|  |  |  |   if (flags & FILE_LOAD_DATA_FILE) { | 
					
						
							|  |  |  |     std::string dataFilename = base::replace_extension(filename, "aseprite-data"); | 
					
						
							|  |  |  |     if (base::is_file(dataFilename)) | 
					
						
							|  |  |  |       fop->m_dataFilename = dataFilename; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | done:; | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   return fop.release(); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  | // static
 | 
					
						
							|  |  |  | FileOp* FileOp::createSaveDocumentOperation(const Context* context, | 
					
						
							| 
									
										
										
										
											2016-06-02 01:49:24 +08:00
										 |  |  |                                             const FileOpROI& roi, | 
					
						
							| 
									
										
										
										
											2017-03-16 10:53:29 +08:00
										 |  |  |                                             const std::string& filename, | 
					
						
							|  |  |  |                                             const std::string& filenameFormatArg) | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-08-09 04:27:26 +08:00
										 |  |  |   std::unique_ptr<FileOp> fop( | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |     new FileOp(FileOpSave, const_cast<Context*>(context))); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-15 06:58:11 +08:00
										 |  |  |   // Document to save
 | 
					
						
							| 
									
										
										
										
											2018-07-07 22:54:44 +08:00
										 |  |  |   fop->m_document = const_cast<Doc*>(roi.document()); | 
					
						
							| 
									
										
										
										
											2016-06-02 01:49:24 +08:00
										 |  |  |   fop->m_roi = roi; | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-15 06:58:11 +08:00
										 |  |  |   // Get the extension of the filename (in lower case)
 | 
					
						
							| 
									
										
										
										
											2017-03-16 10:53:29 +08:00
										 |  |  |   LOG("FILE: Saving document \"%s\"\n", filename.c_str()); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-18 05:00:45 +08:00
										 |  |  |   // Check for read-only attribute
 | 
					
						
							|  |  |  |   if (base::has_readonly_attr(filename)) { | 
					
						
							|  |  |  |     fop->setError("Error saving \"%s\" file, it's read-only", | 
					
						
							|  |  |  |                   filename.c_str()); | 
					
						
							|  |  |  |     return fop.release(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 10:39:20 +08:00
										 |  |  |   // Get the format through the extension of the filename
 | 
					
						
							| 
									
										
										
										
											2016-10-27 06:37:42 +08:00
										 |  |  |   fop->m_format = FileFormatsManager::instance()->getFileFormat( | 
					
						
							| 
									
										
										
										
											2017-09-23 02:57:38 +08:00
										 |  |  |     dio::detect_format_by_file_extension(filename)); | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   if (!fop->m_format || | 
					
						
							|  |  |  |       !fop->m_format->support(FILE_SUPPORT_SAVE)) { | 
					
						
							| 
									
										
										
										
											2016-10-27 06:37:42 +08:00
										 |  |  |     fop->setError("%s can't save \"%s\" file (\"%s\")\n", PACKAGE, | 
					
						
							| 
									
										
										
										
											2017-03-16 10:53:29 +08:00
										 |  |  |                   filename.c_str(), base::get_file_extension(filename).c_str()); | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |     return fop.release(); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-15 06:58:11 +08:00
										 |  |  |   // Warnings
 | 
					
						
							| 
									
										
										
										
											2014-04-21 06:53:27 +08:00
										 |  |  |   std::string warnings; | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   bool fatal = false; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-01 03:53:30 +08:00
										 |  |  |   // Check image type support
 | 
					
						
							| 
									
										
										
										
											2016-07-05 22:44:58 +08:00
										 |  |  |   // TODO add support to automatically convert the image to a supported format
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   switch (fop->m_document->sprite()->pixelFormat()) { | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     case IMAGE_RGB: | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |       if (!(fop->m_format->support(FILE_SUPPORT_RGB))) { | 
					
						
							| 
									
										
										
										
											2017-10-18 05:00:45 +08:00
										 |  |  |         warnings += "<<- " + Strings::alerts_file_format_rgb_mode(); | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |         fatal = true; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2013-10-15 06:58:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |       if (!(fop->m_format->support(FILE_SUPPORT_RGBA)) && | 
					
						
							|  |  |  |           fop->m_document->sprite()->needAlpha()) { | 
					
						
							| 
									
										
										
										
											2013-10-15 06:58:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-18 05:00:45 +08:00
										 |  |  |         warnings += "<<- " + Strings::alerts_file_format_alpha_channel(); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |       } | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case IMAGE_GRAYSCALE: | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |       if (!(fop->m_format->support(FILE_SUPPORT_GRAY))) { | 
					
						
							| 
									
										
										
										
											2017-10-18 05:00:45 +08:00
										 |  |  |         warnings += "<<- " + Strings::alerts_file_format_grayscale_mode(); | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |         fatal = true; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |       if (!(fop->m_format->support(FILE_SUPPORT_GRAYA)) && | 
					
						
							|  |  |  |           fop->m_document->sprite()->needAlpha()) { | 
					
						
							| 
									
										
										
										
											2013-10-15 06:58:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-18 05:00:45 +08:00
										 |  |  |         warnings += "<<- " + Strings::alerts_file_format_alpha_channel(); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |       } | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case IMAGE_INDEXED: | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |       if (!(fop->m_format->support(FILE_SUPPORT_INDEXED))) { | 
					
						
							| 
									
										
										
										
											2017-10-18 05:00:45 +08:00
										 |  |  |         warnings += "<<- " + Strings::alerts_file_format_indexed_mode(); | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |         fatal = true; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |       } | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-10 00:57:16 +08:00
										 |  |  |   // Frames support
 | 
					
						
							| 
									
										
										
										
											2016-06-02 01:49:24 +08:00
										 |  |  |   if (fop->m_roi.frames() > 1) { | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |     if (!fop->m_format->support(FILE_SUPPORT_FRAMES) && | 
					
						
							|  |  |  |         !fop->m_format->support(FILE_SUPPORT_SEQUENCES)) { | 
					
						
							| 
									
										
										
										
											2017-10-18 05:00:45 +08:00
										 |  |  |       warnings += "<<- " + Strings::alerts_file_format_frames(); | 
					
						
							| 
									
										
										
										
											2011-01-17 04:27:18 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-10 00:57:16 +08:00
										 |  |  |   // Layers support
 | 
					
						
							| 
									
										
										
										
											2016-06-08 06:38:56 +08:00
										 |  |  |   if (fop->m_document->sprite()->root()->layersCount() > 1) { | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |     if (!(fop->m_format->support(FILE_SUPPORT_LAYERS))) { | 
					
						
							| 
									
										
										
										
											2017-10-18 05:00:45 +08:00
										 |  |  |       warnings += "<<- " + Strings::alerts_file_format_layers(); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-10 00:57:16 +08:00
										 |  |  |   // Palettes support
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   if (fop->m_document->sprite()->getPalettes().size() > 1) { | 
					
						
							|  |  |  |     if (!fop->m_format->support(FILE_SUPPORT_PALETTES) && | 
					
						
							|  |  |  |         !fop->m_format->support(FILE_SUPPORT_SEQUENCES)) { | 
					
						
							| 
									
										
										
										
											2017-10-18 05:00:45 +08:00
										 |  |  |       warnings += "<<- " + Strings::alerts_file_format_palette_changes(); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-10 00:57:16 +08:00
										 |  |  |   // Check frames support
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   if (!fop->m_document->sprite()->frameTags().empty()) { | 
					
						
							|  |  |  |     if (!fop->m_format->support(FILE_SUPPORT_FRAME_TAGS)) { | 
					
						
							| 
									
										
										
										
											2017-10-18 05:00:45 +08:00
										 |  |  |       warnings += "<<- " + Strings::alerts_file_format_frame_tags(); | 
					
						
							| 
									
										
										
										
											2015-03-10 00:57:16 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-01 00:34:55 +08:00
										 |  |  |   // Big palettes
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   if (!fop->m_format->support(FILE_SUPPORT_BIG_PALETTES)) { | 
					
						
							|  |  |  |     for (const Palette* pal : fop->m_document->sprite()->getPalettes()) { | 
					
						
							| 
									
										
										
										
											2015-07-01 00:34:55 +08:00
										 |  |  |       if (pal->size() > 256) { | 
					
						
							|  |  |  |         warnings += "<<- Palettes with more than 256 colors"; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-01 04:41:25 +08:00
										 |  |  |   // Palette with alpha
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   if (!fop->m_format->support(FILE_SUPPORT_PALETTE_WITH_ALPHA)) { | 
					
						
							| 
									
										
										
										
											2015-07-01 04:41:25 +08:00
										 |  |  |     bool done = false; | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |     for (const Palette* pal : fop->m_document->sprite()->getPalettes()) { | 
					
						
							| 
									
										
										
										
											2015-07-01 04:41:25 +08:00
										 |  |  |       for (int c=0; c<pal->size(); ++c) { | 
					
						
							|  |  |  |         if (rgba_geta(pal->getEntry(c)) < 255) { | 
					
						
							|  |  |  |           warnings += "<<- Palette with alpha channel"; | 
					
						
							|  |  |  |           done = true; | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       if (done) | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-15 06:58:11 +08:00
										 |  |  |   // Show the confirmation alert
 | 
					
						
							|  |  |  |   if (!warnings.empty()) { | 
					
						
							| 
									
										
										
										
											2018-05-07 11:11:50 +08:00
										 |  |  | #ifdef ENABLE_UI
 | 
					
						
							| 
									
										
										
										
											2013-10-15 06:58:11 +08:00
										 |  |  |     // Interative
 | 
					
						
							| 
									
										
										
										
											2015-05-19 04:04:31 +08:00
										 |  |  |     if (context && context->isUIAvailable()) { | 
					
						
							| 
									
										
										
										
											2018-02-08 04:25:58 +08:00
										 |  |  |       int ret = OptionalAlert::show( | 
					
						
							|  |  |  |         Preferences::instance().saveFile.showFileFormatDoesntSupportAlert, | 
					
						
							|  |  |  |         1, // Yes is the default option when the alert dialog is disabled
 | 
					
						
							| 
									
										
										
										
											2017-10-18 05:00:45 +08:00
										 |  |  |         fmt::format( | 
					
						
							|  |  |  |           (fatal ? Strings::alerts_file_format_doesnt_support_error(): | 
					
						
							|  |  |  |                    Strings::alerts_file_format_doesnt_support_warning()), | 
					
						
							|  |  |  |           fop->m_format->name(), | 
					
						
							|  |  |  |           warnings)); | 
					
						
							| 
									
										
										
										
											2015-03-12 03:15:09 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       // Operation can't be done (by fatal error) or the user cancel
 | 
					
						
							|  |  |  |       // the operation
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |       if ((fatal) || (ret != 1)) | 
					
						
							|  |  |  |         return nullptr; | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-10-15 06:58:11 +08:00
										 |  |  |     // No interactive & fatal error?
 | 
					
						
							| 
									
										
										
										
											2018-05-07 11:11:50 +08:00
										 |  |  |     else | 
					
						
							|  |  |  | #endif // ENABLE_UI
 | 
					
						
							|  |  |  |     if (fatal) { | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |       fop->setError(warnings.c_str()); | 
					
						
							|  |  |  |       return fop.release(); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-17 04:27:18 +08:00
										 |  |  |   // Use the "sequence" interface.
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   if (fop->m_format->support(FILE_SUPPORT_SEQUENCES)) { | 
					
						
							|  |  |  |     fop->prepareForSequence(); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-06 23:01:08 +08:00
										 |  |  |     std::string fn = filename; | 
					
						
							| 
									
										
										
										
											2016-06-01 03:53:30 +08:00
										 |  |  |     std::string fn_format = filenameFormatArg; | 
					
						
							| 
									
										
										
										
											2015-01-26 09:36:32 +08:00
										 |  |  |     if (fn_format.empty()) { | 
					
						
							| 
									
										
										
										
											2016-06-07 00:57:35 +08:00
										 |  |  |       fn_format = get_default_filename_format( | 
					
						
							|  |  |  |         fn, | 
					
						
							|  |  |  |         true,                       // With path
 | 
					
						
							|  |  |  |         (fop->m_roi.frames() > 1),  // Has frames
 | 
					
						
							|  |  |  |         false,                      // Doesn't have layers
 | 
					
						
							|  |  |  |         false);                     // Doesn't have tags
 | 
					
						
							| 
									
										
										
										
											2015-01-26 09:36:32 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-07 00:57:35 +08:00
										 |  |  |     Sprite* spr = fop->m_document->sprite(); | 
					
						
							| 
									
										
										
										
											2016-09-17 12:01:28 +08:00
										 |  |  |     frame_t outputFrame = 0; | 
					
						
							| 
									
										
										
										
											2015-05-01 04:02:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-17 12:01:28 +08:00
										 |  |  |     for (frame_t frame : fop->m_roi.selectedFrames()) { | 
					
						
							| 
									
										
										
										
											2016-06-07 00:57:35 +08:00
										 |  |  |       FrameTag* innerTag = (fop->m_roi.frameTag() ? fop->m_roi.frameTag(): spr->frameTags().innerTag(frame)); | 
					
						
							|  |  |  |       FrameTag* outerTag = (fop->m_roi.frameTag() ? fop->m_roi.frameTag(): spr->frameTags().outerTag(frame)); | 
					
						
							|  |  |  |       FilenameInfo fnInfo; | 
					
						
							|  |  |  |       fnInfo | 
					
						
							|  |  |  |         .filename(fn) | 
					
						
							| 
									
										
										
										
											2017-04-12 05:45:51 +08:00
										 |  |  |         .sliceName(fop->m_roi.slice() ? fop->m_roi.slice()->name(): "") | 
					
						
							| 
									
										
										
										
											2016-06-07 00:57:35 +08:00
										 |  |  |         .innerTagName(innerTag ? innerTag->name(): "") | 
					
						
							|  |  |  |         .outerTagName(outerTag ? outerTag->name(): "") | 
					
						
							| 
									
										
										
										
											2016-09-17 12:01:28 +08:00
										 |  |  |         .frame(outputFrame) | 
					
						
							| 
									
										
										
										
											2016-06-07 04:47:47 +08:00
										 |  |  |         .tagFrame(innerTag ? frame - innerTag->fromFrame(): | 
					
						
							| 
									
										
										
										
											2016-09-17 12:01:28 +08:00
										 |  |  |                              outputFrame); | 
					
						
							| 
									
										
										
										
											2016-06-07 00:57:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       fop->m_seq.filename_list.push_back( | 
					
						
							|  |  |  |         filename_formatter(fn_format, fnInfo)); | 
					
						
							| 
									
										
										
										
											2016-09-17 12:01:28 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       ++outputFrame; | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-07 11:11:50 +08:00
										 |  |  | #ifdef ENABLE_UI
 | 
					
						
							| 
									
										
										
										
											2016-06-07 00:57:35 +08:00
										 |  |  |     if (context && context->isUIAvailable() && | 
					
						
							|  |  |  |         fop->m_seq.filename_list.size() > 1 && | 
					
						
							| 
									
										
										
										
											2018-02-08 04:25:58 +08:00
										 |  |  |         OptionalAlert::show( | 
					
						
							|  |  |  |           Preferences::instance().saveFile.showExportAnimationInSequenceAlert, | 
					
						
							|  |  |  |           1, | 
					
						
							| 
									
										
										
										
											2017-10-18 05:00:45 +08:00
										 |  |  |           fmt::format( | 
					
						
							|  |  |  |             Strings::alerts_export_animation_in_sequence(), | 
					
						
							|  |  |  |             int(fop->m_seq.filename_list.size()), | 
					
						
							|  |  |  |             base::get_file_name(fop->m_seq.filename_list[0]), | 
					
						
							|  |  |  |             base::get_file_name(fop->m_seq.filename_list[1]))) != 1) { | 
					
						
							| 
									
										
										
										
											2016-06-07 00:57:35 +08:00
										 |  |  |       return nullptr; | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-05-07 11:11:50 +08:00
										 |  |  | #endif // ENABLE_UI
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |     fop->m_filename = filename; | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-19 06:30:42 +08:00
										 |  |  |   // Configure output format?
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   if (fop->m_format->support(FILE_SUPPORT_GET_FORMAT_OPTIONS)) { | 
					
						
							| 
									
										
										
										
											2016-06-02 02:01:07 +08:00
										 |  |  |     base::SharedPtr<FormatOptions> opts = | 
					
						
							| 
									
										
										
										
											2018-08-09 04:27:26 +08:00
										 |  |  |       fop->m_format->getFormatOptions(fop.get()); | 
					
						
							| 
									
										
										
										
											2008-03-29 11:43:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-17 04:27:18 +08:00
										 |  |  |     // Does the user cancelled the operation?
 | 
					
						
							| 
									
										
										
										
											2016-06-02 02:01:07 +08:00
										 |  |  |     if (!opts) | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |       return nullptr; | 
					
						
							| 
									
										
										
										
											2008-03-29 11:43:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-02 02:01:07 +08:00
										 |  |  |     fop->m_formatOptions = opts; | 
					
						
							|  |  |  |     fop->m_document->setFormatOptions(opts); | 
					
						
							| 
									
										
										
										
											2008-03-29 11:43:19 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-07 06:27:43 +08:00
										 |  |  |   // Does data file exist?
 | 
					
						
							|  |  |  |   std::string dataFilename = base::replace_extension(filename, "aseprite-data"); | 
					
						
							|  |  |  |   if (base::is_file(dataFilename)) | 
					
						
							|  |  |  |     fop->m_dataFilename = dataFilename; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   return fop.release(); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-23 08:11:25 +08:00
										 |  |  | // Executes the file operation: loads or saves the sprite.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // It can be called from a different thread of the one used
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  | // by FileOp::createLoadDocumentOperation() or createSaveDocumentOperation().
 | 
					
						
							| 
									
										
										
										
											2011-03-23 08:11:25 +08:00
										 |  |  | //
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  | // After this function you must to mark the FileOp as "done" calling
 | 
					
						
							|  |  |  | // FileOp::done() function.
 | 
					
						
							| 
									
										
										
										
											2017-04-12 05:45:51 +08:00
										 |  |  | //
 | 
					
						
							|  |  |  | // TODO refactor this code
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  | void FileOp::operate(IFileOpProgress* progress) | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   ASSERT(!isDone()); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   m_progressInterface = progress; | 
					
						
							| 
									
										
										
										
											2012-07-06 12:06:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-23 08:11:25 +08:00
										 |  |  |   // Load //////////////////////////////////////////////////////////////////////
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   if (m_type == FileOpLoad && | 
					
						
							|  |  |  |       m_format != NULL && | 
					
						
							|  |  |  |       m_format->support(FILE_SUPPORT_LOAD)) { | 
					
						
							| 
									
										
										
										
											2011-03-23 08:11:25 +08:00
										 |  |  |     // Load a sequence
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |     if (isSequence()) { | 
					
						
							| 
									
										
										
										
											2011-03-23 08:11:25 +08:00
										 |  |  |       // Default palette
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |       m_seq.palette->makeBlack(); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-04 21:58:14 +08:00
										 |  |  |       // Load the sequence
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |       frame_t frames(m_seq.filename_list.size()); | 
					
						
							| 
									
										
										
										
											2014-12-29 07:39:11 +08:00
										 |  |  |       frame_t frame(0); | 
					
						
							| 
									
										
										
										
											2015-09-29 05:49:34 +08:00
										 |  |  |       Image* old_image = nullptr; | 
					
						
							| 
									
										
										
										
											2018-05-25 02:37:01 +08:00
										 |  |  |       gfx::Size canvasSize(0, 0); | 
					
						
							| 
									
										
										
										
											2015-09-29 05:49:34 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-12 05:45:51 +08:00
										 |  |  |       // TODO setPalette for each frame???
 | 
					
						
							| 
									
										
										
										
											2015-09-29 05:49:34 +08:00
										 |  |  |       auto add_image = [&]() { | 
					
						
							| 
									
										
										
										
											2018-05-25 02:37:01 +08:00
										 |  |  |         canvasSize |= m_seq.image->size(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |         m_seq.last_cel->data()->setImage(m_seq.image); | 
					
						
							|  |  |  |         m_seq.layer->addCel(m_seq.last_cel); | 
					
						
							| 
									
										
										
										
											2015-09-29 05:49:34 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |         if (m_document->sprite()->palette(frame) | 
					
						
							|  |  |  |             ->countDiff(m_seq.palette, NULL, NULL) > 0) { | 
					
						
							|  |  |  |           m_seq.palette->setFrame(frame); | 
					
						
							|  |  |  |           m_document->sprite()->setPalette(m_seq.palette, true); | 
					
						
							| 
									
										
										
										
											2015-09-29 05:49:34 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |         old_image = m_seq.image.get(); | 
					
						
							|  |  |  |         m_seq.image.reset(NULL); | 
					
						
							|  |  |  |         m_seq.last_cel = NULL; | 
					
						
							| 
									
										
										
										
											2015-09-29 05:49:34 +08:00
										 |  |  |       }; | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |       m_seq.has_alpha = false; | 
					
						
							|  |  |  |       m_seq.progress_offset = 0.0f; | 
					
						
							|  |  |  |       m_seq.progress_fraction = 1.0f / (double)frames; | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |       auto it = m_seq.filename_list.begin(), | 
					
						
							|  |  |  |            end = m_seq.filename_list.end(); | 
					
						
							| 
									
										
										
										
											2010-11-06 22:59:03 +08:00
										 |  |  |       for (; it != end; ++it) { | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |         m_filename = it->c_str(); | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // Call the "load" procedure to read the first bitmap.
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |         bool loadres = m_format->load(this); | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |         if (!loadres) { | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |           setError("Error loading frame %d from file \"%s\"\n", | 
					
						
							|  |  |  |                    frame+1, m_filename.c_str()); | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // For the first frame...
 | 
					
						
							|  |  |  |         if (!old_image) { | 
					
						
							|  |  |  |           // Error reading the first frame
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |           if (!loadres || !m_document || !m_seq.last_cel) { | 
					
						
							|  |  |  |             m_seq.image.reset(); | 
					
						
							|  |  |  |             delete m_seq.last_cel; | 
					
						
							|  |  |  |             delete m_document; | 
					
						
							|  |  |  |             m_document = nullptr; | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |             break; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           // Read ok
 | 
					
						
							|  |  |  |           else { | 
					
						
							| 
									
										
										
										
											2013-03-31 06:53:52 +08:00
										 |  |  |             // Add the keyframe
 | 
					
						
							| 
									
										
										
										
											2015-09-29 05:49:34 +08:00
										 |  |  |             add_image(); | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2013-03-31 06:53:52 +08:00
										 |  |  |         // For other frames
 | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |         else { | 
					
						
							| 
									
										
										
										
											2013-03-31 06:53:52 +08:00
										 |  |  |           // All done (or maybe not enough memory)
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |           if (!loadres || !m_seq.last_cel) { | 
					
						
							|  |  |  |             m_seq.image.reset(); | 
					
						
							|  |  |  |             delete m_seq.last_cel; | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |             break; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-31 06:53:52 +08:00
										 |  |  |           // Compare the old frame with the new one
 | 
					
						
							|  |  |  | #if USE_LINK // TODO this should be configurable through a check-box
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |           if (count_diff_between_images(old_image, m_seq.image)) { | 
					
						
							| 
									
										
										
										
											2015-09-29 05:49:34 +08:00
										 |  |  |             add_image(); | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2013-03-31 06:53:52 +08:00
										 |  |  |           // We don't need this image
 | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |           else { | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |             delete m_seq.image; | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-31 06:53:52 +08:00
										 |  |  |             // But add a link frame
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |             m_seq.last_cel->image = image_index; | 
					
						
							|  |  |  |             layer_add_frame(m_seq.layer, m_seq.last_cel); | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |             m_seq.last_image = NULL; | 
					
						
							|  |  |  |             m_seq.last_cel = NULL; | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2015-09-29 05:49:34 +08:00
										 |  |  |           add_image(); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-09 08:09:09 +08:00
										 |  |  |         ++frame; | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |         m_seq.progress_offset += m_seq.progress_fraction; | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |       m_filename = *m_seq.filename_list.begin(); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |       // Final setup
 | 
					
						
							| 
									
										
										
										
											2018-05-25 02:37:01 +08:00
										 |  |  |       if (m_document) { | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |         // Configure the layer as the 'Background'
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |         if (!m_seq.has_alpha) | 
					
						
							|  |  |  |           m_seq.layer->configureAsBackground(); | 
					
						
							| 
									
										
										
										
											2008-03-29 11:43:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-25 02:37:01 +08:00
										 |  |  |         // Set the final canvas size (as the bigger loaded
 | 
					
						
							|  |  |  |         // frame/image).
 | 
					
						
							|  |  |  |         m_document->sprite()->setSize(canvasSize.w, | 
					
						
							|  |  |  |                                       canvasSize.h); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |         // Set the frames range
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |         m_document->sprite()->setTotalFrames(frame); | 
					
						
							| 
									
										
										
										
											2008-03-27 22:29:33 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |         // Sets special options from the specific format (e.g. BMP
 | 
					
						
							|  |  |  |         // file can contain the number of bits per pixel).
 | 
					
						
							| 
									
										
										
										
											2016-06-02 02:01:07 +08:00
										 |  |  |         m_document->setFormatOptions(m_formatOptions); | 
					
						
							| 
									
										
										
										
											2008-03-27 22:29:33 +08:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-03-23 08:11:25 +08:00
										 |  |  |     // Direct load from one file.
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |     else { | 
					
						
							| 
									
										
										
										
											2011-03-23 08:11:25 +08:00
										 |  |  |       // Call the "load" procedure.
 | 
					
						
							| 
									
										
										
										
											2017-03-07 06:27:43 +08:00
										 |  |  |       if (!m_format->load(this)) { | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |         setError("Error loading sprite from file \"%s\"\n", | 
					
						
							|  |  |  |                  m_filename.c_str()); | 
					
						
							| 
									
										
										
										
											2017-03-07 06:27:43 +08:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Load special data from .aseprite-data file
 | 
					
						
							|  |  |  |     if (m_document && | 
					
						
							|  |  |  |         m_document->sprite()  && | 
					
						
							|  |  |  |         !m_dataFilename.empty()) { | 
					
						
							| 
									
										
										
										
											2017-04-12 23:35:13 +08:00
										 |  |  |       try { | 
					
						
							|  |  |  |         load_aseprite_data_file(m_dataFilename, m_document); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       catch (const std::exception& ex) { | 
					
						
							|  |  |  |         setError("Error loading data file: %s\n", ex.what()); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-03-23 08:11:25 +08:00
										 |  |  |   // Save //////////////////////////////////////////////////////////////////////
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   else if (m_type == FileOpSave && | 
					
						
							|  |  |  |            m_format != NULL && | 
					
						
							|  |  |  |            m_format->support(FILE_SUPPORT_SAVE)) { | 
					
						
							| 
									
										
										
										
											2014-04-10 11:33:28 +08:00
										 |  |  | #ifdef ENABLE_SAVE
 | 
					
						
							| 
									
										
										
										
											2011-03-23 08:11:25 +08:00
										 |  |  |     // Save a sequence
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |     if (isSequence()) { | 
					
						
							|  |  |  |       ASSERT(m_format->support(FILE_SUPPORT_SEQUENCES)); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |       Sprite* sprite = m_document->sprite(); | 
					
						
							| 
									
										
										
										
											2011-03-23 08:11:25 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       // Create a temporary bitmap
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |       m_seq.image.reset(Image::create(sprite->pixelFormat(), | 
					
						
							| 
									
										
										
										
											2017-04-12 05:45:51 +08:00
										 |  |  |                                       sprite->width(), | 
					
						
							|  |  |  |                                       sprite->height())); | 
					
						
							| 
									
										
										
										
											2015-01-04 21:58:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |       m_seq.progress_offset = 0.0f; | 
					
						
							|  |  |  |       m_seq.progress_fraction = 1.0f / (double)sprite->totalFrames(); | 
					
						
							| 
									
										
										
										
											2015-01-04 21:58:14 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       // For each frame in the sprite.
 | 
					
						
							|  |  |  |       render::Render render; | 
					
						
							| 
									
										
										
										
											2016-09-17 12:01:28 +08:00
										 |  |  |       frame_t outputFrame = 0; | 
					
						
							|  |  |  |       for (frame_t frame : m_roi.selectedFrames()) { | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |         // Draw the "frame" in "m_seq.image"
 | 
					
						
							| 
									
										
										
										
											2017-04-12 05:45:51 +08:00
										 |  |  |         if (m_roi.slice()) { | 
					
						
							|  |  |  |           const SliceKey* key = m_roi.slice()->getByFrame(frame); | 
					
						
							|  |  |  |           if (!key || key->isEmpty()) | 
					
						
							|  |  |  |             continue;           // Skip frame because there is no slice key
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           m_seq.image.reset( | 
					
						
							|  |  |  |             Image::create(sprite->pixelFormat(), | 
					
						
							|  |  |  |                           key->bounds().w, | 
					
						
							|  |  |  |                           key->bounds().h)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           render.renderSprite( | 
					
						
							|  |  |  |             m_seq.image.get(), sprite, frame, | 
					
						
							|  |  |  |             gfx::Clip(gfx::Point(0, 0), key->bounds())); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           render.renderSprite(m_seq.image.get(), sprite, frame); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-01-04 21:58:14 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // Setup the palette.
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |         sprite->palette(frame)->copyColorsTo(m_seq.palette); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-04 21:58:14 +08:00
										 |  |  |         // Setup the filename to be used.
 | 
					
						
							| 
									
										
										
										
											2016-09-17 12:01:28 +08:00
										 |  |  |         m_filename = m_seq.filename_list[outputFrame]; | 
					
						
							| 
									
										
										
										
											2015-01-04 21:58:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-29 02:08:49 +08:00
										 |  |  |         // Make directories
 | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           std::string dir = base::get_file_path(m_filename); | 
					
						
							|  |  |  |           try { | 
					
						
							|  |  |  |             if (!base::is_directory(dir)) | 
					
						
							|  |  |  |               base::make_all_directories(dir); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           catch (const std::exception& ex) { | 
					
						
							|  |  |  |             // Ignore errors and make the delegate fail
 | 
					
						
							|  |  |  |             setError("Error creating directory \"%s\"\n%s", | 
					
						
							|  |  |  |                      dir.c_str(), ex.what()); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-04 21:58:14 +08:00
										 |  |  |         // Call the "save" procedure... did it fail?
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |         if (!m_format->save(this)) { | 
					
						
							|  |  |  |           setError("Error saving frame %d in the file \"%s\"\n", | 
					
						
							| 
									
										
										
										
											2016-09-17 12:01:28 +08:00
										 |  |  |                    outputFrame+1, m_filename.c_str()); | 
					
						
							| 
									
										
										
										
											2015-01-04 21:58:14 +08:00
										 |  |  |           break; | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |         m_seq.progress_offset += m_seq.progress_fraction; | 
					
						
							| 
									
										
										
										
											2016-09-17 12:01:28 +08:00
										 |  |  |         ++outputFrame; | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-12-23 05:07:06 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |       m_filename = *m_seq.filename_list.begin(); | 
					
						
							| 
									
										
										
										
											2015-01-04 21:58:14 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       // Destroy the image
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |       m_seq.image.reset(NULL); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-03-23 08:11:25 +08:00
										 |  |  |     // Direct save to a file.
 | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |     else { | 
					
						
							| 
									
										
										
										
											2011-03-23 08:11:25 +08:00
										 |  |  |       // Call the "save" procedure.
 | 
					
						
							| 
									
										
										
										
											2017-03-07 06:27:43 +08:00
										 |  |  |       if (!m_format->save(this)) { | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |         setError("Error saving the sprite in the file \"%s\"\n", | 
					
						
							|  |  |  |                  m_filename.c_str()); | 
					
						
							| 
									
										
										
										
											2017-03-07 06:27:43 +08:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Save special data from .aseprite-data file
 | 
					
						
							|  |  |  |     if (m_document && | 
					
						
							|  |  |  |         m_document->sprite() && | 
					
						
							|  |  |  |         !hasError() && | 
					
						
							|  |  |  |         !m_dataFilename.empty()) { | 
					
						
							| 
									
										
										
										
											2017-04-12 23:35:13 +08:00
										 |  |  |       try { | 
					
						
							|  |  |  |         save_aseprite_data_file(m_dataFilename, m_document); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       catch (const std::exception& ex) { | 
					
						
							|  |  |  |         setError("Error loading data file: %s\n", ex.what()); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-04-10 11:33:28 +08:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |     setError( | 
					
						
							| 
									
										
										
										
											2014-04-10 11:33:28 +08:00
										 |  |  |       "Save operation is not supported in trial version.\n" | 
					
						
							|  |  |  |       "Go to " WEBSITE_DOWNLOAD " and get the full-version."); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-23 08:11:25 +08:00
										 |  |  |   // Progress = 100%
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   setProgress(1.0f); | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-23 08:11:25 +08:00
										 |  |  | // After mark the 'fop' as 'done' you must to free it calling fop_free().
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  | void FileOp::done() | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-23 08:11:25 +08:00
										 |  |  |   // Finally done.
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   scoped_lock lock(m_mutex); | 
					
						
							|  |  |  |   m_done = true; | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  | void FileOp::stop() | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   scoped_lock lock(m_mutex); | 
					
						
							|  |  |  |   if (!m_done) | 
					
						
							|  |  |  |     m_stop = true; | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-06 12:06:00 +08:00
										 |  |  | FileOp::~FileOp() | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   if (m_format) | 
					
						
							|  |  |  |     m_format->destroyData(this); | 
					
						
							| 
									
										
										
										
											2011-06-26 04:12:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   delete m_seq.palette; | 
					
						
							| 
									
										
										
										
											2012-07-06 12:06:00 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-06-01 04:15:38 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-29 11:53:24 +08:00
										 |  |  | void FileOp::createDocument(Sprite* spr) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   // spr can be NULL if the sprite is set in onPostLoad() then
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   ASSERT(m_document == NULL); | 
					
						
							| 
									
										
										
										
											2018-07-07 22:54:44 +08:00
										 |  |  |   m_document = new Doc(spr); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  | void FileOp::postLoad() | 
					
						
							| 
									
										
										
										
											2011-06-26 04:12:08 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   if (m_document == NULL) | 
					
						
							| 
									
										
										
										
											2011-06-26 04:12:08 +08:00
										 |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Set the filename.
 | 
					
						
							| 
									
										
										
										
											2016-04-12 06:17:39 +08:00
										 |  |  |   std::string fn; | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   if (isSequence()) | 
					
						
							| 
									
										
										
										
											2016-04-12 06:17:39 +08:00
										 |  |  |     fn = m_seq.filename_list.begin()->c_str(); | 
					
						
							| 
									
										
										
										
											2011-06-26 04:12:08 +08:00
										 |  |  |   else | 
					
						
							| 
									
										
										
										
											2016-04-12 06:17:39 +08:00
										 |  |  |     fn = m_filename.c_str(); | 
					
						
							|  |  |  |   m_document->setFilename(fn); | 
					
						
							| 
									
										
										
										
											2011-06-26 04:12:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   bool result = m_format->postLoad(this); | 
					
						
							| 
									
										
										
										
											2011-06-26 04:12:08 +08:00
										 |  |  |   if (!result) { | 
					
						
							|  |  |  |     // Destroy the document
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |     delete m_document; | 
					
						
							|  |  |  |     m_document = nullptr; | 
					
						
							| 
									
										
										
										
											2011-06-26 04:12:08 +08:00
										 |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   Sprite* sprite = m_document->sprite(); | 
					
						
							| 
									
										
										
										
											2015-05-21 21:17:59 +08:00
										 |  |  |   if (sprite) { | 
					
						
							| 
									
										
										
										
											2011-06-26 04:12:08 +08:00
										 |  |  |     // Creates a suitable palette for RGB images
 | 
					
						
							| 
									
										
										
										
											2015-05-21 21:17:59 +08:00
										 |  |  |     if (sprite->pixelFormat() == IMAGE_RGB && | 
					
						
							|  |  |  |         sprite->getPalettes().size() <= 1 && | 
					
						
							|  |  |  |         sprite->palette(frame_t(0))->isBlack()) { | 
					
						
							|  |  |  |       base::SharedPtr<Palette> palette( | 
					
						
							| 
									
										
										
										
											2015-08-20 23:37:58 +08:00
										 |  |  |         render::create_palette_from_sprite( | 
					
						
							| 
									
										
										
										
											2015-07-23 05:26:25 +08:00
										 |  |  |           sprite, frame_t(0), sprite->lastFrame(), true, | 
					
						
							|  |  |  |           nullptr, nullptr)); | 
					
						
							| 
									
										
										
										
											2015-05-21 21:17:59 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       sprite->resetPalettes(); | 
					
						
							|  |  |  |       sprite->setPalette(palette.get(), false); | 
					
						
							| 
									
										
										
										
											2011-06-26 04:12:08 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   m_document->markAsSaved(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-02 02:01:07 +08:00
										 |  |  | base::SharedPtr<FormatOptions> FileOp::formatOptions() const | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-02 02:01:07 +08:00
										 |  |  |   return m_formatOptions; | 
					
						
							| 
									
										
										
										
											2011-06-26 04:12:08 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-02 02:01:07 +08:00
										 |  |  | void FileOp::setFormatOptions(const base::SharedPtr<FormatOptions>& opts) | 
					
						
							| 
									
										
										
										
											2008-03-27 22:29:33 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-02 02:01:07 +08:00
										 |  |  |   ASSERT(!m_formatOptions); | 
					
						
							|  |  |  |   m_formatOptions = opts; | 
					
						
							| 
									
										
										
										
											2008-03-27 22:29:33 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  | void FileOp::sequenceSetNColors(int ncolors) | 
					
						
							| 
									
										
										
										
											2015-07-01 05:16:10 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   m_seq.palette->resize(ncolors); | 
					
						
							| 
									
										
										
										
											2015-07-01 05:16:10 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  | int FileOp::sequenceGetNColors() const | 
					
						
							| 
									
										
										
										
											2015-07-01 05:16:10 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   return m_seq.palette->size(); | 
					
						
							| 
									
										
										
										
											2015-07-01 05:16:10 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  | void FileOp::sequenceSetColor(int index, int r, int g, int b) | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   m_seq.palette->setEntry(index, rgba(r, g, b, 255)); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  | void FileOp::sequenceGetColor(int index, int* r, int* g, int* b) const | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-07-01 00:34:55 +08:00
										 |  |  |   uint32_t c; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ASSERT(index >= 0); | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   if (index >= 0 && index < m_seq.palette->size()) | 
					
						
							|  |  |  |     c = m_seq.palette->getEntry(index); | 
					
						
							| 
									
										
										
										
											2015-07-01 00:34:55 +08:00
										 |  |  |   else | 
					
						
							|  |  |  |     c = rgba(0, 0, 0, 255);     // Black color
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-10 06:59:05 +08:00
										 |  |  |   *r = rgba_getr(c); | 
					
						
							|  |  |  |   *g = rgba_getg(c); | 
					
						
							|  |  |  |   *b = rgba_getb(c); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  | void FileOp::sequenceSetAlpha(int index, int a) | 
					
						
							| 
									
										
										
										
											2015-07-01 05:08:14 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   int c = m_seq.palette->getEntry(index); | 
					
						
							| 
									
										
										
										
											2015-07-01 05:08:14 +08:00
										 |  |  |   int r = rgba_getr(c); | 
					
						
							|  |  |  |   int g = rgba_getg(c); | 
					
						
							|  |  |  |   int b = rgba_getb(c); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   m_seq.palette->setEntry(index, rgba(r, g, b, a)); | 
					
						
							| 
									
										
										
										
											2015-07-01 05:08:14 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  | void FileOp::sequenceGetAlpha(int index, int* a) const | 
					
						
							| 
									
										
										
										
											2015-07-01 05:08:14 +08:00
										 |  |  | { | 
					
						
							|  |  |  |   ASSERT(index >= 0); | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   if (index >= 0 && index < m_seq.palette->size()) | 
					
						
							|  |  |  |     *a = rgba_geta(m_seq.palette->getEntry(index)); | 
					
						
							| 
									
										
										
										
											2015-07-01 05:08:14 +08:00
										 |  |  |   else | 
					
						
							|  |  |  |     *a = 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  | Image* FileOp::sequenceImage(PixelFormat pixelFormat, int w, int h) | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-17 21:12:26 +08:00
										 |  |  |   Sprite* sprite; | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-28 23:15:32 +08:00
										 |  |  |   // Create the image
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   if (!m_document) { | 
					
						
							| 
									
										
										
										
											2012-02-13 10:21:06 +08:00
										 |  |  |     sprite = new Sprite(pixelFormat, w, h, 256); | 
					
						
							| 
									
										
										
										
											2009-11-17 21:12:26 +08:00
										 |  |  |     try { | 
					
						
							|  |  |  |       LayerImage* layer = new LayerImage(sprite); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-28 23:15:32 +08:00
										 |  |  |       // Add the layer
 | 
					
						
							| 
									
										
										
										
											2016-06-08 06:38:56 +08:00
										 |  |  |       sprite->root()->addLayer(layer); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-28 23:15:32 +08:00
										 |  |  |       // Done
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |       createDocument(sprite); | 
					
						
							|  |  |  |       m_seq.layer = layer; | 
					
						
							| 
									
										
										
										
											2009-11-17 21:12:26 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |     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 { | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |     sprite = m_document->sprite(); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-30 12:28:15 +08:00
										 |  |  |     if (sprite->pixelFormat() != pixelFormat) | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |       return nullptr; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   if (m_seq.last_cel) { | 
					
						
							| 
									
										
										
										
											2016-09-19 23:39:53 +08:00
										 |  |  |     setError("Error: called two times FileOp::sequenceImage()\n"); | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |     return nullptr; | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-23 08:11:25 +08:00
										 |  |  |   // Create a bitmap
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   m_seq.image.reset(Image::create(pixelFormat, w, h)); | 
					
						
							|  |  |  |   m_seq.last_cel = new Cel(m_seq.frame++, ImageRef(nullptr)); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   return m_seq.image.get(); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  | void FileOp::setError(const char *format, ...) | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-03-07 06:27:43 +08:00
										 |  |  |   char buf_error[4096];         // TODO possible stack overflow
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   va_list ap; | 
					
						
							|  |  |  |   va_start(ap, format); | 
					
						
							| 
									
										
										
										
											2014-09-22 00:42:46 +08:00
										 |  |  |   vsnprintf(buf_error, sizeof(buf_error), format, ap); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   va_end(ap); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-06 22:59:03 +08:00
										 |  |  |   // Concatenate the new error
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |     scoped_lock lock(m_mutex); | 
					
						
							|  |  |  |     m_error += buf_error; | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  | void FileOp::setProgress(double progress) | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   scoped_lock lock(m_mutex); | 
					
						
							| 
									
										
										
										
											2010-03-10 10:34:50 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   if (isSequence()) { | 
					
						
							|  |  |  |     m_progress = | 
					
						
							|  |  |  |       m_seq.progress_offset + | 
					
						
							|  |  |  |       m_seq.progress_fraction*progress; | 
					
						
							| 
									
										
										
										
											2010-03-10 10:34:50 +08:00
										 |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |     m_progress = progress; | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-07-06 12:06:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   if (m_progressInterface) | 
					
						
							|  |  |  |     m_progressInterface->ackFileOpProgress(progress); | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-21 21:39:30 +08:00
										 |  |  | void FileOp::getFilenameList(base::paths& output) const | 
					
						
							| 
									
										
										
										
											2016-06-01 03:49:24 +08:00
										 |  |  | { | 
					
						
							|  |  |  |   if (isSequence()) { | 
					
						
							|  |  |  |     output = m_seq.filename_list; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     output.push_back(m_filename); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  | double FileOp::progress() const | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-07-06 12:06:00 +08:00
										 |  |  |   double progress; | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |     scoped_lock lock(m_mutex); | 
					
						
							|  |  |  |     progress = m_progress; | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   } | 
					
						
							|  |  |  |   return progress; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  | // Returns true when the file operation has finished, this means, when
 | 
					
						
							|  |  |  | // the FileOp::operate() routine ends.
 | 
					
						
							|  |  |  | bool FileOp::isDone() const | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | { | 
					
						
							|  |  |  |   bool done; | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |     scoped_lock lock(m_mutex); | 
					
						
							|  |  |  |     done = m_done; | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   } | 
					
						
							|  |  |  |   return done; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  | bool FileOp::isStop() const | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | { | 
					
						
							|  |  |  |   bool stop; | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |     scoped_lock lock(m_mutex); | 
					
						
							|  |  |  |     stop = m_stop; | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   } | 
					
						
							|  |  |  |   return stop; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  | FileOp::FileOp(FileOpType type, Context* context) | 
					
						
							|  |  |  |   : m_type(type) | 
					
						
							|  |  |  |   , m_format(nullptr) | 
					
						
							|  |  |  |   , m_context(context) | 
					
						
							|  |  |  |   , m_document(nullptr) | 
					
						
							|  |  |  |   , m_progress(0.0) | 
					
						
							|  |  |  |   , m_progressInterface(nullptr) | 
					
						
							|  |  |  |   , m_done(false) | 
					
						
							|  |  |  |   , m_stop(false) | 
					
						
							|  |  |  |   , m_oneframe(false) | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   m_seq.palette = nullptr; | 
					
						
							|  |  |  |   m_seq.image.reset(nullptr); | 
					
						
							|  |  |  |   m_seq.progress_offset = 0.0f; | 
					
						
							|  |  |  |   m_seq.progress_fraction = 0.0f; | 
					
						
							|  |  |  |   m_seq.frame = frame_t(0); | 
					
						
							|  |  |  |   m_seq.layer = nullptr; | 
					
						
							|  |  |  |   m_seq.last_cel = nullptr; | 
					
						
							| 
									
										
										
										
											2016-11-16 05:11:47 +08:00
										 |  |  |   m_seq.flags = 0; | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  | void FileOp::prepareForSequence() | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-09-29 22:27:00 +08:00
										 |  |  |   m_seq.palette = new Palette(frame_t(0), 256); | 
					
						
							| 
									
										
										
										
											2016-06-02 02:01:07 +08:00
										 |  |  |   m_formatOptions.reset(); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-06 08:20:19 +08:00
										 |  |  | } // namespace app
 |