1 // Aseprite 2 // Copyright (C) 2001-2018 David Capello 3 // 4 // This program is distributed under the terms of 5 // the End-User License Agreement for Aseprite. 6 7 #ifndef APP_FILE_FILE_H_INCLUDED 8 #define APP_FILE_FILE_H_INCLUDED 9 #pragma once 10 11 #include "base/mutex.h" 12 #include "base/paths.h" 13 #include "base/shared_ptr.h" 14 #include "doc/frame.h" 15 #include "doc/image_ref.h" 16 #include "doc/pixel_format.h" 17 #include "doc/selected_frames.h" 18 19 #include <cstdio> 20 #include <string> 21 22 // Flags for FileOp::createLoadDocumentOperation() 23 #define FILE_LOAD_SEQUENCE_NONE 0x00000001 24 #define FILE_LOAD_SEQUENCE_ASK 0x00000002 25 #define FILE_LOAD_SEQUENCE_ASK_CHECKBOX 0x00000004 26 #define FILE_LOAD_SEQUENCE_YES 0x00000008 27 #define FILE_LOAD_ONE_FRAME 0x00000010 28 #define FILE_LOAD_DATA_FILE 0x00000020 29 30 namespace doc { 31 class FrameTag; 32 } 33 34 namespace doc { 35 class Cel; 36 class Image; 37 class Layer; 38 class LayerImage; 39 class Palette; 40 class Slice; 41 class Sprite; 42 } 43 44 namespace app { 45 46 class Context; 47 class Doc; 48 class FileFormat; 49 class FormatOptions; 50 51 using namespace doc; 52 53 // File operations. 54 typedef enum { 55 FileOpLoad, 56 FileOpSave 57 } FileOpType; 58 59 class IFileOpProgress { 60 public: ~IFileOpProgress()61 virtual ~IFileOpProgress() { } 62 virtual void ackFileOpProgress(double progress) = 0; 63 }; 64 65 class FileOpROI { // Region of interest 66 public: 67 FileOpROI(); 68 FileOpROI(const Doc* doc, 69 const std::string& sliceName, 70 const std::string& frameTagName, 71 const doc::SelectedFrames& selFrames, 72 const bool adjustByFrameTag); 73 document()74 const Doc* document() const { return m_document; } slice()75 doc::Slice* slice() const { return m_slice; } frameTag()76 doc::FrameTag* frameTag() const { return m_frameTag; } fromFrame()77 doc::frame_t fromFrame() const { return m_selFrames.firstFrame(); } toFrame()78 doc::frame_t toFrame() const { return m_selFrames.lastFrame(); } selectedFrames()79 const doc::SelectedFrames& selectedFrames() const { return m_selFrames; } 80 frames()81 doc::frame_t frames() const { 82 return (doc::frame_t)m_selFrames.size(); 83 } 84 85 private: 86 const Doc* m_document; 87 doc::Slice* m_slice; 88 doc::FrameTag* m_frameTag; 89 doc::SelectedFrames m_selFrames; 90 }; 91 92 // Structure to load & save files. 93 // 94 // TODO This class do to many things. There should be a previous 95 // instance (class) to verify what the user want to do with the 96 // sequence of files, and the result of that operation should be the 97 // input of this one. 98 class FileOp { 99 public: 100 static FileOp* createLoadDocumentOperation(Context* context, 101 const std::string& filename, 102 int flags); 103 104 static FileOp* createSaveDocumentOperation(const Context* context, 105 const FileOpROI& roi, 106 const std::string& filename, 107 const std::string& filenameFormat); 108 109 ~FileOp(); 110 isSequence()111 bool isSequence() const { return !m_seq.filename_list.empty(); } isOneFrame()112 bool isOneFrame() const { return m_oneframe; } 113 filename()114 const std::string& filename() const { return m_filename; } filenames()115 const base::paths& filenames() const { return m_seq.filename_list; } context()116 Context* context() const { return m_context; } document()117 Doc* document() const { return m_document; } releaseDocument()118 Doc* releaseDocument() { 119 Doc* doc = m_document; 120 m_document = nullptr; 121 return doc; 122 } 123 roi()124 const FileOpROI& roi() const { return m_roi; } 125 126 void createDocument(Sprite* spr); 127 void operate(IFileOpProgress* progress = nullptr); 128 129 void done(); 130 void stop(); 131 bool isDone() const; 132 bool isStop() const; 133 134 // Does extra post-load processing which may require user intervention. 135 void postLoad(); 136 137 // Special options specific to the file format. 138 base::SharedPtr<FormatOptions> formatOptions() const; 139 void setFormatOptions(const base::SharedPtr<FormatOptions>& opts); 140 141 // Helpers for file decoder/encoder (FileFormat) with 142 // FILE_SUPPORT_SEQUENCES flag. 143 void sequenceSetNColors(int ncolors); 144 int sequenceGetNColors() const; 145 void sequenceSetColor(int index, int r, int g, int b); 146 void sequenceGetColor(int index, int* r, int* g, int* b) const; 147 void sequenceSetAlpha(int index, int a); 148 void sequenceGetAlpha(int index, int* a) const; 149 Image* sequenceImage(PixelFormat pixelFormat, int w, int h); sequenceImage()150 const Image* sequenceImage() const { return m_seq.image.get(); } sequenceGetHasAlpha()151 bool sequenceGetHasAlpha() const { 152 return m_seq.has_alpha; 153 } sequenceSetHasAlpha(bool hasAlpha)154 void sequenceSetHasAlpha(bool hasAlpha) { 155 m_seq.has_alpha = hasAlpha; 156 } sequenceFlags()157 int sequenceFlags() const { 158 return m_seq.flags; 159 } 160 error()161 const std::string& error() const { return m_error; } 162 void setError(const char *error, ...); hasError()163 bool hasError() const { return !m_error.empty(); } 164 165 double progress() const; 166 void setProgress(double progress); 167 168 void getFilenameList(base::paths& output) const; 169 170 private: 171 FileOp(); // Undefined 172 FileOp(FileOpType type, Context* context); 173 174 FileOpType m_type; // Operation type: 0=load, 1=save. 175 FileFormat* m_format; 176 Context* m_context; 177 // TODO this should be a shared pointer (and we should remove 178 // releaseDocument() member function) 179 Doc* m_document; // Loaded document, or document to be saved. 180 std::string m_filename; // File-name to load/save. 181 std::string m_dataFilename; // File-name for a special XML .aseprite-data where extra sprite data can be stored 182 FileOpROI m_roi; 183 184 // Shared fields between threads. 185 mutable base::mutex m_mutex; // Mutex to access to the next two fields. 186 double m_progress; // Progress (1.0 is ready). 187 IFileOpProgress* m_progressInterface; 188 std::string m_error; // Error string. 189 bool m_done; // True if the operation finished. 190 bool m_stop; // Force the break of the operation. 191 bool m_oneframe; // Load just one frame (in formats 192 // that support animation like 193 // GIF/FLI/ASE). 194 195 base::SharedPtr<FormatOptions> m_formatOptions; 196 197 // Data for sequences. 198 struct { 199 base::paths filename_list; // All file names to load/save. 200 Palette* palette; // Palette of the sequence. 201 ImageRef image; // Image to be saved/loaded. 202 // For the progress bar. 203 double progress_offset; // Progress offset from the current frame. 204 double progress_fraction; // Progress fraction for one frame. 205 // To load sequences. 206 frame_t frame; 207 bool has_alpha; 208 LayerImage* layer; 209 Cel* last_cel; 210 // Flags after the user choose what to do with the sequence. 211 int flags; 212 } m_seq; 213 214 void prepareForSequence(); 215 }; 216 217 // Available extensions for each load/save operation. 218 base::paths get_readable_extensions(); 219 base::paths get_writable_extensions(); 220 221 // High-level routines to load/save documents. 222 Doc* load_document(Context* context, const std::string& filename); 223 int save_document(Context* context, Doc* document); 224 225 // Returns true if the given filename contains a file extension that 226 // can be used to save only static images (i.e. animations are saved 227 // as sequence of files). 228 bool is_static_image_format(const std::string& filename); 229 230 } // namespace app 231 232 #endif 233