[aseprite] 100/250: Convert FileOp into a class

Tobias Hansen thansen at moszumanska.debian.org
Sun Dec 20 15:27:17 UTC 2015


This is an automated email from the git hooks/post-receive script.

thansen pushed a commit to branch master
in repository aseprite.

commit c30112ea10c6ba7ea53c55dfc8b876df0a894174
Author: David Capello <davidcapello at gmail.com>
Date:   Tue Sep 29 11:27:00 2015 -0300

    Convert FileOp into a class
---
 src/app/commands/cmd_open_file.cpp |  34 +--
 src/app/commands/cmd_save_file.cpp |  20 +-
 src/app/file/ase_format.cpp        | 115 ++++----
 src/app/file/bmp_format.cpp        |  32 +-
 src/app/file/file.cpp              | 583 ++++++++++++++++++-------------------
 src/app/file/file.h                | 139 +++++----
 src/app/file/file_format.h         |   2 +-
 src/app/file/fli_format.cpp        |  22 +-
 src/app/file/gif_format.cpp        |  29 +-
 src/app/file/ico_format.cpp        |  10 +-
 src/app/file/jpeg_format.cpp       |  40 +--
 src/app/file/palette_file.cpp      |  29 +-
 src/app/file/pcx_format.cpp        |  34 +--
 src/app/file/png_format.cpp        |  78 ++---
 src/app/file/tga_format.cpp        |  34 +--
 src/app/file/webp_format.cpp       | 116 ++++----
 src/app/thumbnail_generator.cpp    |  65 ++---
 17 files changed, 698 insertions(+), 684 deletions(-)

diff --git a/src/app/commands/cmd_open_file.cpp b/src/app/commands/cmd_open_file.cpp
index b772ce3..145b2e2 100644
--- a/src/app/commands/cmd_open_file.cpp
+++ b/src/app/commands/cmd_open_file.cpp
@@ -60,7 +60,7 @@ public:
     startJob();
 
     if (isCanceled())
-      fop_stop(m_fop);
+      m_fop->stop();
 
     waitJob();
   }
@@ -69,18 +69,16 @@ private:
   // Thread to do the hard work: load the file from the disk.
   virtual void onJob() override {
     try {
-      fop_operate(m_fop, this);
+      m_fop->operate(this);
     }
     catch (const std::exception& e) {
-      fop_error(m_fop, "Error loading file:\n%s", e.what());
+      m_fop->setError("Error loading file:\n%s", e.what());
     }
 
-    if (fop_is_stop(m_fop) && m_fop->document) {
-      delete m_fop->document;
-      m_fop->document = NULL;
-    }
+    if (m_fop->isStop() && m_fop->document())
+      delete m_fop->releaseDocument();
 
-    fop_done(m_fop);
+    m_fop->done();
   }
 
   virtual void ackFileOpProgress(double progress) override {
@@ -121,12 +119,14 @@ void OpenFileCommand::onExecute(Context* context)
   }
 
   if (!m_filename.empty()) {
-    base::UniquePtr<FileOp> fop(fop_to_load_document(context, m_filename.c_str(), FILE_LOAD_SEQUENCE_ASK));
+    base::UniquePtr<FileOp> fop(
+      FileOp::createLoadDocumentOperation(
+        context, m_filename.c_str(), FILE_LOAD_SEQUENCE_ASK));
     bool unrecent = false;
 
     if (fop) {
-      if (fop->has_error()) {
-        console.printf(fop->error.c_str());
+      if (fop->hasError()) {
+        console.printf(fop->error().c_str());
         unrecent = true;
       }
       else {
@@ -134,20 +134,20 @@ void OpenFileCommand::onExecute(Context* context)
         task.showProgressWindow();
 
         // Post-load processing, it is called from the GUI because may require user intervention.
-        fop_post_load(fop);
+        fop->postLoad();
 
         // Show any error
-        if (fop->has_error())
-          console.printf(fop->error.c_str());
+        if (fop->hasError())
+          console.printf(fop->error().c_str());
 
-        Document* document = fop->document;
+        Document* document = fop->document();
         if (document) {
           if (context->isUIAvailable())
-            App::instance()->getRecentFiles()->addRecentFile(fop->filename.c_str());
+            App::instance()->getRecentFiles()->addRecentFile(fop->filename().c_str());
 
           document->setContext(context);
         }
-        else if (!fop_is_stop(fop))
+        else if (!fop->isStop())
           unrecent = true;
       }
 
diff --git a/src/app/commands/cmd_save_file.cpp b/src/app/commands/cmd_save_file.cpp
index 1d9d374..90c62ec 100644
--- a/src/app/commands/cmd_save_file.cpp
+++ b/src/app/commands/cmd_save_file.cpp
@@ -68,7 +68,7 @@ public:
     startJob();
 
     if (isCanceled()) {
-      fop_stop(m_fop);
+      m_fop->stop();
     }
 
     waitJob();
@@ -79,12 +79,12 @@ private:
   // Thread to do the hard work: save the file to the disk.
   virtual void onJob() override {
     try {
-      fop_operate(m_fop, this);
+      m_fop->operate(this);
     }
     catch (const std::exception& e) {
-      fop_error(m_fop, "Error saving file:\n%s", e.what());
+      m_fop->setError("Error saving file:\n%s", e.what());
     }
-    fop_done(m_fop);
+    m_fop->done();
   }
 
   virtual void ackFileOpProgress(double progress) override {
@@ -98,24 +98,26 @@ static void save_document_in_background(const Context* context,
                                         const Document* document, bool mark_as_saved,
                                         const std::string& fn_format)
 {
-  base::UniquePtr<FileOp> fop(fop_to_save_document(context,
-      document, document->filename().c_str(), fn_format.c_str()));
+  base::UniquePtr<FileOp> fop(
+    FileOp::createSaveDocumentOperation(
+      context, document,
+      document->filename().c_str(), fn_format.c_str()));
   if (!fop)
     return;
 
   SaveFileJob job(fop);
   job.showProgressWindow();
 
-  if (fop->has_error()) {
+  if (fop->hasError()) {
     Console console;
-    console.printf(fop->error.c_str());
+    console.printf(fop->error().c_str());
 
     // We don't know if the file was saved correctly or not. So mark
     // it as it should be saved again.
     const_cast<Document*>(document)->impossibleToBackToSavedState();
   }
   // If the job was cancelled, mark the document as modified.
-  else if (fop_is_stop(fop)) {
+  else if (fop->isStop()) {
     const_cast<Document*>(document)->impossibleToBackToSavedState();
   }
   else if (context->isUIAvailable()) {
diff --git a/src/app/file/ase_format.cpp b/src/app/file/ase_format.cpp
index cf7fbd1..1b77c37 100644
--- a/src/app/file/ase_format.cpp
+++ b/src/app/file/ase_format.cpp
@@ -90,8 +90,8 @@ static void ase_file_read_frame_header(FILE* f, ASE_FrameHeader* frame_header);
 static void ase_file_prepare_frame_header(FILE* f, ASE_FrameHeader* frame_header);
 static void ase_file_write_frame_header(FILE* f, ASE_FrameHeader* frame_header);
 
-static void ase_file_write_layers(FILE* f, ASE_FrameHeader* frame_header, Layer* layer);
-static void ase_file_write_cels(FILE* f, ASE_FrameHeader* frame_header, Sprite* sprite, Layer* layer, frame_t frame);
+static void ase_file_write_layers(FILE* f, ASE_FrameHeader* frame_header, const Layer* layer);
+static void ase_file_write_cels(FILE* f, ASE_FrameHeader* frame_header, const Sprite* sprite, const Layer* layer, frame_t frame);
 
 static void ase_file_read_padding(FILE* f, int bytes);
 static void ase_file_write_padding(FILE* f, int bytes);
@@ -104,18 +104,18 @@ static void ase_file_write_close_chunk(FILE* f, ASE_Chunk* chunk);
 static Palette* ase_file_read_color_chunk(FILE* f, Palette* prevPal, frame_t frame);
 static Palette* ase_file_read_color2_chunk(FILE* f, Palette* prevPal, frame_t frame);
 static Palette* ase_file_read_palette_chunk(FILE* f, Palette* prevPal, frame_t frame);
-static void ase_file_write_color2_chunk(FILE* f, ASE_FrameHeader* frame_header, Palette* pal);
-static void ase_file_write_palette_chunk(FILE* f, ASE_FrameHeader* frame_header, Palette* pal, int from, int to);
+static void ase_file_write_color2_chunk(FILE* f, ASE_FrameHeader* frame_header, const Palette* pal);
+static void ase_file_write_palette_chunk(FILE* f, ASE_FrameHeader* frame_header, const Palette* pal, int from, int to);
 static Layer* ase_file_read_layer_chunk(FILE* f, ASE_Header* header, Sprite* sprite, Layer** previous_layer, int* current_level);
-static void ase_file_write_layer_chunk(FILE* f, ASE_FrameHeader* frame_header, Layer* layer);
+static void ase_file_write_layer_chunk(FILE* f, ASE_FrameHeader* frame_header, const Layer* layer);
 static Cel* ase_file_read_cel_chunk(FILE* f, Sprite* sprite, frame_t frame, PixelFormat pixelFormat, FileOp* fop, ASE_Header* header, size_t chunk_end);
-static void ase_file_write_cel_chunk(FILE* f, ASE_FrameHeader* frame_header, Cel* cel, LayerImage* layer, Sprite* sprite);
+static void ase_file_write_cel_chunk(FILE* f, ASE_FrameHeader* frame_header, const Cel* cel, const LayerImage* layer, const Sprite* sprite);
 static Mask* ase_file_read_mask_chunk(FILE* f);
 #if 0
 static void ase_file_write_mask_chunk(FILE* f, ASE_FrameHeader* frame_header, Mask* mask);
 #endif
 static void ase_file_read_frame_tags_chunk(FILE* f, FrameTags* frameTags);
-static void ase_file_write_frame_tags_chunk(FILE* f, ASE_FrameHeader* frame_header, FrameTags* frameTags);
+static void ase_file_write_frame_tags_chunk(FILE* f, ASE_FrameHeader* frame_header, const FrameTags* frameTags);
 
 class ChunkWriter {
 public:
@@ -165,13 +165,13 @@ FileFormat* CreateAseFormat()
 
 bool AseFormat::onLoad(FileOp* fop)
 {
-  FileHandle handle(open_file_with_exception(fop->filename, "rb"));
+  FileHandle handle(open_file_with_exception(fop->filename(), "rb"));
   FILE* f = handle.get();
   bool ignore_old_color_chunks = false;
 
   ASE_Header header;
   if (!ase_file_read_header(f, &header)) {
-    fop_error(fop, "Error reading header\n");
+    fop->setError("Error reading header\n");
     return false;
   }
 
@@ -195,7 +195,7 @@ bool AseFormat::onLoad(FileOp* fop)
   for (frame_t frame(0); frame<sprite->totalFrames(); ++frame) {
     // Start frame position
     int frame_pos = ftell(f);
-    fop_progress(fop, (float)frame_pos / (float)header.size);
+    fop->setProgress((float)frame_pos / (float)header.size);
 
     // Read frame header
     ASE_FrameHeader frame_header;
@@ -211,7 +211,7 @@ bool AseFormat::onLoad(FileOp* fop)
       for (int c=0; c<frame_header.chunks; c++) {
         /* start chunk position */
         int chunk_pos = ftell(f);
-        fop_progress(fop, (float)chunk_pos / (float)header.size);
+        fop->setProgress((float)chunk_pos / (float)header.size);
 
         // Read chunk information
         int chunk_size = fgetl(f);
@@ -244,7 +244,7 @@ bool AseFormat::onLoad(FileOp* fop)
           }
 
           case ASE_FILE_CHUNK_LAYER: {
-            /* fop_error(fop, "Layer chunk\n"); */
+            /* fop->setError("Layer chunk\n"); */
 
             ase_file_read_layer_chunk(f, &header, sprite,
                                       &last_layer,
@@ -253,7 +253,7 @@ bool AseFormat::onLoad(FileOp* fop)
           }
 
           case ASE_FILE_CHUNK_CEL: {
-            /* fop_error(fop, "Cel chunk\n"); */
+            /* fop->setError("Cel chunk\n"); */
 
             ase_file_read_cel_chunk(f, sprite, frame,
                                     sprite->pixelFormat(), fop, &header,
@@ -264,19 +264,19 @@ bool AseFormat::onLoad(FileOp* fop)
           case ASE_FILE_CHUNK_MASK: {
             Mask* mask;
 
-            /* fop_error(fop, "Mask chunk\n"); */
+            /* fop->setError("Mask chunk\n"); */
 
             mask = ase_file_read_mask_chunk(f);
             if (mask)
               delete mask;      // TODO add the mask in some place?
             else
-              fop_error(fop, "Warning: error loading a mask chunk\n");
+              fop->setError("Warning: error loading a mask chunk\n");
 
             break;
           }
 
           case ASE_FILE_CHUNK_PATH:
-            /* fop_error(fop, "Path chunk\n"); */
+            /* fop->setError("Path chunk\n"); */
             break;
 
           case ASE_FILE_CHUNK_FRAME_TAGS:
@@ -284,7 +284,7 @@ bool AseFormat::onLoad(FileOp* fop)
             break;
 
           default:
-            fop_error(fop, "Warning: Unsupported chunk type %d (skipping)\n", chunk_type);
+            fop->setError("Warning: Unsupported chunk type %d (skipping)\n", chunk_type);
             break;
         }
 
@@ -297,10 +297,10 @@ bool AseFormat::onLoad(FileOp* fop)
     fseek(f, frame_pos+frame_header.size, SEEK_SET);
 
     // Just one frame?
-    if (fop->oneframe)
+    if (fop->isOneFrame())
       break;
 
-    if (fop_is_stop(fop))
+    if (fop->isStop())
       break;
   }
 
@@ -308,7 +308,7 @@ bool AseFormat::onLoad(FileOp* fop)
   sprite.release();
 
   if (ferror(f)) {
-    fop_error(fop, "Error reading file.\n");
+    fop->setError("Error reading file.\n");
     return false;
   }
   else {
@@ -317,10 +317,11 @@ bool AseFormat::onLoad(FileOp* fop)
 }
 
 #ifdef ENABLE_SAVE
+
 bool AseFormat::onSave(FileOp* fop)
 {
-  Sprite* sprite = fop->document->sprite();
-  FileHandle handle(open_file_with_exception(fop->filename, "wb"));
+  const Sprite* sprite = fop->document()->sprite();
+  FileHandle handle(open_file_with_exception(fop->filename(), "wb"));
   FILE* f = handle.get();
 
   // Write the header
@@ -382,9 +383,9 @@ bool AseFormat::onSave(FileOp* fop)
 
     // Progress
     if (sprite->totalFrames() > 1)
-      fop_progress(fop, float(frame+1) / float(sprite->totalFrames()));
+      fop->setProgress(float(frame+1) / float(sprite->totalFrames()));
 
-    if (fop_is_stop(fop))
+    if (fop->isStop())
       break;
   }
 
@@ -392,14 +393,15 @@ bool AseFormat::onSave(FileOp* fop)
   ase_file_write_header_filesize(f, &header);
 
   if (ferror(f)) {
-    fop_error(fop, "Error writing file.\n");
+    fop->setError("Error writing file.\n");
     return false;
   }
   else {
     return true;
   }
 }
-#endif
+
+#endif  // ENABLE_SAVE
 
 static bool ase_file_read_header(FILE* f, ASE_Header* header)
 {
@@ -525,34 +527,34 @@ static void ase_file_write_frame_header(FILE* f, ASE_FrameHeader* frame_header)
   fseek(f, end, SEEK_SET);
 }
 
-static void ase_file_write_layers(FILE* f, ASE_FrameHeader* frame_header, Layer* layer)
+static void ase_file_write_layers(FILE* f, ASE_FrameHeader* frame_header, const Layer* layer)
 {
   ase_file_write_layer_chunk(f, frame_header, layer);
 
   if (layer->isFolder()) {
-    LayerIterator it = static_cast<LayerFolder*>(layer)->getLayerBegin();
-    LayerIterator end = static_cast<LayerFolder*>(layer)->getLayerEnd();
+    auto it = static_cast<const LayerFolder*>(layer)->getLayerBegin(),
+         end = static_cast<const LayerFolder*>(layer)->getLayerEnd();
 
     for (; it != end; ++it)
       ase_file_write_layers(f, frame_header, *it);
   }
 }
 
-static void ase_file_write_cels(FILE* f, ASE_FrameHeader* frame_header, Sprite* sprite, Layer* layer, frame_t frame)
+static void ase_file_write_cels(FILE* f, ASE_FrameHeader* frame_header, const Sprite* sprite, const Layer* layer, frame_t frame)
 {
   if (layer->isImage()) {
-    Cel* cel = layer->cel(frame);
+    const Cel* cel = layer->cel(frame);
     if (cel) {
-/*       fop_error(fop, "New cel in frame %d, in layer %d\n", */
+/*       fop->setError("New cel in frame %d, in layer %d\n", */
 /*                   frame, sprite_layer2index(sprite, layer)); */
 
-      ase_file_write_cel_chunk(f, frame_header, cel, static_cast<LayerImage*>(layer), sprite);
+      ase_file_write_cel_chunk(f, frame_header, cel, static_cast<const LayerImage*>(layer), sprite);
     }
   }
 
   if (layer->isFolder()) {
-    LayerIterator it = static_cast<LayerFolder*>(layer)->getLayerBegin();
-    LayerIterator end = static_cast<LayerFolder*>(layer)->getLayerEnd();
+    auto it = static_cast<const LayerFolder*>(layer)->getLayerBegin(),
+         end = static_cast<const LayerFolder*>(layer)->getLayerEnd();
 
     for (; it != end; ++it)
       ase_file_write_cels(f, frame_header, sprite, *it, frame);
@@ -700,7 +702,7 @@ static Palette* ase_file_read_palette_chunk(FILE* f, Palette* prevPal, frame_t f
   return pal;
 }
 
-static void ase_file_write_color2_chunk(FILE* f, ASE_FrameHeader* frame_header, Palette* pal)
+static void ase_file_write_color2_chunk(FILE* f, ASE_FrameHeader* frame_header, const Palette* pal)
 {
   ChunkWriter chunk(f, frame_header, ASE_FILE_CHUNK_FLI_COLOR2);
   int c, color;
@@ -718,7 +720,7 @@ static void ase_file_write_color2_chunk(FILE* f, ASE_FrameHeader* frame_header,
   }
 }
 
-static void ase_file_write_palette_chunk(FILE* f, ASE_FrameHeader* frame_header, Palette* pal, int from, int to)
+static void ase_file_write_palette_chunk(FILE* f, ASE_FrameHeader* frame_header, const Palette* pal, int from, int to)
 {
   ChunkWriter chunk(f, frame_header, ASE_FILE_CHUNK_PALETTE);
 
@@ -795,7 +797,7 @@ static Layer* ase_file_read_layer_chunk(FILE* f, ASE_Header* header, Sprite* spr
   return layer;
 }
 
-static void ase_file_write_layer_chunk(FILE* f, ASE_FrameHeader* frame_header, Layer* layer)
+static void ase_file_write_layer_chunk(FILE* f, ASE_FrameHeader* frame_header, const Layer* layer)
 {
   ChunkWriter chunk(f, frame_header, ASE_FILE_CHUNK_LAYER);
 
@@ -817,8 +819,8 @@ static void ase_file_write_layer_chunk(FILE* f, ASE_FrameHeader* frame_header, L
   // Default width & height, and blend mode
   fputw(0, f);
   fputw(0, f);
-  fputw(layer->isImage() ? (int)static_cast<LayerImage*>(layer)->blendMode(): 0, f);
-  fputc(layer->isImage() ? (int)static_cast<LayerImage*>(layer)->opacity(): 0, f);
+  fputw(layer->isImage() ? (int)static_cast<const LayerImage*>(layer)->blendMode(): 0, f);
+  fputc(layer->isImage() ? (int)static_cast<const LayerImage*>(layer)->opacity(): 0, f);
 
   // padding
   ase_file_write_padding(f, 3);
@@ -826,7 +828,7 @@ static void ase_file_write_layer_chunk(FILE* f, ASE_FrameHeader* frame_header, L
   /* layer name */
   ase_file_write_string(f, layer->name());
 
-  /* fop_error(fop, "Layer name \"%s\" child level: %d\n", layer->name, child_level); */
+  /* fop->setError("Layer name \"%s\" child level: %d\n", layer->name, child_level); */
 }
 
 //////////////////////////////////////////////////////////////////////
@@ -945,12 +947,12 @@ static void read_raw_image(FILE* f, Image* image, FileOp* fop, ASE_Header* heade
     for (x=0; x<image->width(); x++)
       put_pixel_fast<ImageTraits>(image, x, y, pixel_io.read_pixel(f));
 
-    fop_progress(fop, (float)ftell(f) / (float)header->size);
+    fop->setProgress((float)ftell(f) / (float)header->size);
   }
 }
 
 template<typename ImageTraits>
-static void write_raw_image(FILE* f, Image* image)
+static void write_raw_image(FILE* f, const Image* image)
 {
   PixelIO<ImageTraits> pixel_io;
   int x, y;
@@ -1021,7 +1023,7 @@ static void read_compressed_image(FILE* f, Image* image, size_t chunk_end, FileO
       }
     } while (zstream.avail_out == 0);
 
-    fop_progress(fop, (float)ftell(f) / (float)header->size);
+    fop->setProgress((float)ftell(f) / (float)header->size);
   }
 
   uncompressed_offset = 0;
@@ -1040,7 +1042,7 @@ static void read_compressed_image(FILE* f, Image* image, size_t chunk_end, FileO
 }
 
 template<typename ImageTraits>
-static void write_compressed_image(FILE* f, Image* image)
+static void write_compressed_image(FILE* f, const Image* image)
 {
   PixelIO<ImageTraits> pixel_io;
   z_stream zstream;
@@ -1109,13 +1111,13 @@ static Cel* ase_file_read_cel_chunk(FILE* f, Sprite* sprite, frame_t frame,
 
   layer = sprite->indexToLayer(layer_index);
   if (!layer) {
-    fop_error(fop, "Frame %d didn't found layer with index %d\n",
-      (int)frame, (int)layer_index);
+    fop->setError("Frame %d didn't found layer with index %d\n",
+                  (int)frame, (int)layer_index);
     return NULL;
   }
   if (!layer->isImage()) {
-    fop_error(fop, "Invalid .ase file (frame %d in layer %d which does not contain images\n",
-      (int)frame, (int)layer_index);
+    fop->setError("Invalid .ase file (frame %d in layer %d which does not contain images\n",
+                  (int)frame, (int)layer_index);
     return NULL;
   }
 
@@ -1210,7 +1212,7 @@ static Cel* ase_file_read_cel_chunk(FILE* f, Sprite* sprite, frame_t frame,
         // OK, in case of error we can show the problem, but continue
         // loading more cels.
         catch (const std::exception& e) {
-          fop_error(fop, e.what());
+          fop->setError(e.what());
         }
 
         cel.reset(new Cel(frame, image));
@@ -1229,12 +1231,13 @@ static Cel* ase_file_read_cel_chunk(FILE* f, Sprite* sprite, frame_t frame,
   return cel.release();
 }
 
-static void ase_file_write_cel_chunk(FILE* f, ASE_FrameHeader* frame_header, Cel* cel, LayerImage* layer, Sprite* sprite)
+static void ase_file_write_cel_chunk(FILE* f, ASE_FrameHeader* frame_header,
+                                     const Cel* cel, const LayerImage* layer, const Sprite* sprite)
 {
   ChunkWriter chunk(f, frame_header, ASE_FILE_CHUNK_CEL);
 
   int layer_index = sprite->layerToIndex(layer);
-  Cel* link = cel->link();
+  const Cel* link = cel->link();
   int cel_type = (link ? ASE_FILE_LINK_CEL: ASE_FILE_COMPRESSED_CEL);
 
   fputw(layer_index, f);
@@ -1247,7 +1250,7 @@ static void ase_file_write_cel_chunk(FILE* f, ASE_FrameHeader* frame_header, Cel
   switch (cel_type) {
 
     case ASE_FILE_RAW_CEL: {
-      Image* image = cel->image();
+      const Image* image = cel->image();
 
       if (image) {
         // Width and height
@@ -1284,7 +1287,7 @@ static void ase_file_write_cel_chunk(FILE* f, ASE_FrameHeader* frame_header, Cel
       break;
 
     case ASE_FILE_COMPRESSED_CEL: {
-      Image* image = cel->image();
+      const Image* image = cel->image();
 
       if (image) {
         // Width and height
@@ -1409,7 +1412,7 @@ static void ase_file_read_frame_tags_chunk(FILE* f, FrameTags* frameTags)
   }
 }
 
-static void ase_file_write_frame_tags_chunk(FILE* f, ASE_FrameHeader* frame_header, FrameTags* frameTags)
+static void ase_file_write_frame_tags_chunk(FILE* f, ASE_FrameHeader* frame_header, const FrameTags* frameTags)
 {
   ChunkWriter chunk(f, frame_header, ASE_FILE_CHUNK_FRAME_TAGS);
 
@@ -1418,7 +1421,7 @@ static void ase_file_write_frame_tags_chunk(FILE* f, ASE_FrameHeader* frame_head
   fputl(0, f);  // 8 reserved bytes
   fputl(0, f);
 
-  for (FrameTag* tag : *frameTags) {
+  for (const FrameTag* tag : *frameTags) {
     fputw(tag->fromFrame(), f);
     fputw(tag->toFrame(), f);
     fputc((int)tag->aniDir(), f);
diff --git a/src/app/file/bmp_format.cpp b/src/app/file/bmp_format.cpp
index 3f6da02..11ae684 100644
--- a/src/app/file/bmp_format.cpp
+++ b/src/app/file/bmp_format.cpp
@@ -182,7 +182,7 @@ static int read_os2_bminfoheader(FILE *f, BITMAPINFOHEADER *infoheader)
 /* read_bmicolors:
  *  Loads the color palette for 1,4,8 bit formats.
  */
-static void read_bmicolors(FileOp *fop, int bytes, FILE *f, bool win_flag)
+static void read_bmicolors(FileOp* fop, int bytes, FILE *f, bool win_flag)
 {
   int i, j, r, g, b;
 
@@ -191,7 +191,7 @@ static void read_bmicolors(FileOp *fop, int bytes, FILE *f, bool win_flag)
     g = fgetc(f);
     r = fgetc(f);
 
-    fop_sequence_set_color(fop, j, r, g, b);
+    fop->sequenceSetColor(j, r, g, b);
 
     j++;
     i += 3;
@@ -362,8 +362,8 @@ static void read_image(FILE *f, Image *image, const BITMAPINFOHEADER *infoheader
       case 32: read_32bit_line(infoheader->biWidth, f, image, line); break;
     }
 
-    fop_progress(fop, (float)(i+1) / (float)(height));
-    if (fop_is_stop(fop))
+    fop->setProgress((float)(i+1) / (float)(height));
+    if (fop->isStop())
       break;
   }
 }
@@ -602,7 +602,7 @@ bool BmpFormat::onLoad(FileOp *fop)
   PixelFormat pixelFormat;
   int format;
 
-  FileHandle handle(open_file_with_exception(fop->filename, "rb"));
+  FileHandle handle(open_file_with_exception(fop->filename(), "rb"));
   FILE* f = handle.get();
 
   if (read_bmfileheader(f, &fileheader) != 0)
@@ -649,7 +649,7 @@ bool BmpFormat::onLoad(FileOp *fop)
   else
     rmask = gmask = bmask = 0;
 
-  Image* image = fop_sequence_image(fop, pixelFormat,
+  Image* image = fop->sequenceImage(pixelFormat,
                                     infoheader.biWidth,
                                     ABS((int)infoheader.biHeight));
   if (!image) {
@@ -677,23 +677,23 @@ bool BmpFormat::onLoad(FileOp *fop)
 
     case BI_BITFIELDS:
       if (read_bitfields_image(f, image, &infoheader, rmask, gmask, bmask) < 0) {
-        fop_error(fop, "Unsupported bitfields in the BMP file.\n");
+        fop->setError("Unsupported bitfields in the BMP file.\n");
         return false;
       }
       break;
 
     default:
-      fop_error(fop, "Unsupported BMP compression.\n");
+      fop->setError("Unsupported BMP compression.\n");
       return false;
   }
 
   if (ferror(f)) {
-    fop_error(fop, "Error reading file.\n");
+    fop->setError("Error reading file.\n");
     return false;
   }
 
   // Setup the file-data.
-  if (!fop->seq.format_options) {
+  if (!fop->sequenceGetFormatOptions()) {
     base::SharedPtr<BmpOptions> bmp_options(new BmpOptions());
 
     bmp_options->format = format;
@@ -703,7 +703,7 @@ bool BmpFormat::onLoad(FileOp *fop)
     bmp_options->green_mask = gmask;
     bmp_options->blue_mask = bmask;
 
-    fop_sequence_set_format_options(fop, bmp_options);
+    fop->sequenceSetFormatOptions(bmp_options);
   }
 
   return true;
@@ -712,7 +712,7 @@ bool BmpFormat::onLoad(FileOp *fop)
 #ifdef ENABLE_SAVE
 bool BmpFormat::onSave(FileOp *fop)
 {
-  Image* image = fop->seq.image.get();
+  const Image* image = fop->sequenceImage();
   int bfSize;
   int biSizeImage;
   int bpp = (image->pixelFormat() == IMAGE_RGB) ? 24 : 8;
@@ -730,7 +730,7 @@ bool BmpFormat::onSave(FileOp *fop)
     bfSize = 54 + biSizeImage;       /* header + image data */
   }
 
-  FileHandle handle(open_file_with_exception(fop->filename, "wb"));
+  FileHandle handle(open_file_with_exception(fop->filename(), "wb"));
   FILE* f = handle.get();
 
   /* file_header */
@@ -761,7 +761,7 @@ bool BmpFormat::onSave(FileOp *fop)
 
     /* palette */
     for (i=0; i<256; i++) {
-      fop_sequence_get_color(fop, i, &r, &g, &b);
+      fop->sequenceGetColor(i, &r, &g, &b);
       fputc(b, f);
       fputc(g, f);
       fputc(r, f);
@@ -793,11 +793,11 @@ bool BmpFormat::onSave(FileOp *fop)
     for (j=0; j<filler; j++)
       fputc(0, f);
 
-    fop_progress(fop, (float)(image->height()-i) / (float)image->height());
+    fop->setProgress((float)(image->height()-i) / (float)image->height());
   }
 
   if (ferror(f)) {
-    fop_error(fop, "Error writing file.\n");
+    fop->setError("Error writing file.\n");
     return false;
   }
   else {
diff --git a/src/app/file/file.cpp b/src/app/file/file.cpp
index a2559f1..1ca3067 100644
--- a/src/app/file/file.cpp
+++ b/src/app/file/file.cpp
@@ -40,9 +40,6 @@ namespace app {
 
 using namespace base;
 
-static FileOp* fop_new(FileOpType type, Context* context);
-static void fop_prepare_for_sequence(FileOp* fop);
-
 std::string get_readable_extensions()
 {
   std::string buf;
@@ -75,26 +72,23 @@ std::string get_writable_extensions()
 
 Document* load_document(Context* context, const char* filename)
 {
-  Document* document;
-
   /* TODO add a option to configure what to do with the sequence */
-  FileOp *fop = fop_to_load_document(context, filename, FILE_LOAD_SEQUENCE_NONE);
+  base::UniquePtr<FileOp> fop(FileOp::createLoadDocumentOperation(context, filename, FILE_LOAD_SEQUENCE_NONE));
   if (!fop)
-    return NULL;
+    return nullptr;
 
-  /* operate in this same thread */
-  fop_operate(fop, NULL);
-  fop_done(fop);
+  // Operate in this same thread
+  fop->operate();
+  fop->done();
+  fop->postLoad();
 
-  fop_post_load(fop);
-
-  if (fop->has_error()) {
+  if (fop->hasError()) {
     Console console(context);
-    console.printf(fop->error.c_str());
+    console.printf(fop->error().c_str());
   }
 
-  document = fop->document;
-  fop_free(fop);
+  Document* document = fop->releaseDocument();
+  fop.release();
 
   if (document && context)
     document->setContext(context);
@@ -106,35 +100,33 @@ int save_document(Context* context, doc::Document* document)
 {
   ASSERT(dynamic_cast<app::Document*>(document));
 
-  int ret;
-  FileOp* fop = fop_to_save_document(context,
-    static_cast<app::Document*>(document),
-    document->filename().c_str(), "");
+  UniquePtr<FileOp> fop(
+    FileOp::createSaveDocumentOperation(
+      context,
+      static_cast<app::Document*>(document),
+      document->filename().c_str(), ""));
   if (!fop)
     return -1;
 
-  /* operate in this same thread */
-  fop_operate(fop, NULL);
-  fop_done(fop);
+  // Operate in this same thread
+  fop->operate();
+  fop->done();
 
-  if (fop->has_error()) {
+  if (fop->hasError()) {
     Console console(context);
-    console.printf(fop->error.c_str());
+    console.printf(fop->error().c_str());
   }
 
-  ret = (!fop->has_error() ? 0: -1);
-  fop_free(fop);
-
-  return ret;
+  return (!fop->hasError() ? 0: -1);
 }
 
-FileOp* fop_to_load_document(Context* context, const char* filename, int flags)
+// static
+FileOp* FileOp::createLoadDocumentOperation(Context* context, const char* filename, int flags)
 {
-  FileOp *fop;
-
-  fop = fop_new(FileOpLoad, context);
+  base::UniquePtr<FileOp> fop(
+    new FileOp(FileOpLoad, context));
   if (!fop)
-    return NULL;
+    return nullptr;
 
   // Get the extension of the filename (in lower case)
   std::string extension = base::string_to_lower(base::get_file_extension(filename));
@@ -143,27 +135,27 @@ FileOp* fop_to_load_document(Context* context, const char* filename, int flags)
 
   // Does file exist?
   if (!base::is_file(filename)) {
-    fop_error(fop, "File not found: \"%s\"\n", filename);
+    fop->setError("File not found: \"%s\"\n", filename);
     goto done;
   }
 
   // Get the format through the extension of the filename
-  fop->format = FileFormatsManager::instance()
+  fop->m_format = FileFormatsManager::instance()
     ->getFileFormatByExtension(extension.c_str());
 
-  if (!fop->format ||
-      !fop->format->support(FILE_SUPPORT_LOAD)) {
-    fop_error(fop, "ASEPRITE can't load \"%s\" files\n", extension.c_str());
+  if (!fop->m_format ||
+      !fop->m_format->support(FILE_SUPPORT_LOAD)) {
+    fop->setError("ASEPRITE can't load \"%s\" files\n", extension.c_str());
     goto done;
   }
 
   /* use the "sequence" interface */
-  if (fop->format->support(FILE_SUPPORT_SEQUENCES)) {
+  if (fop->m_format->support(FILE_SUPPORT_SEQUENCES)) {
     /* prepare to load a sequence */
-    fop_prepare_for_sequence(fop);
+    fop->prepareForSequence();
 
     /* per now, we want load just one file */
-    fop->seq.filename_list.push_back(filename);
+    fop->m_seq.filename_list.push_back(filename);
 
     /* don't load the sequence (just the one file/one frame) */
     if (!(flags & FILE_LOAD_SEQUENCE_NONE)) {
@@ -187,55 +179,54 @@ FileOp* fop_to_load_document(Context* context, const char* filename, int flags)
             break;
 
           /* add this file name to the list */
-          fop->seq.filename_list.push_back(buf);
+          fop->m_seq.filename_list.push_back(buf);
         }
       }
 
       /* TODO add a better dialog to edit file-names */
       if ((flags & FILE_LOAD_SEQUENCE_ASK) && context && context->isUIAvailable()) {
         /* really want load all files? */
-        if ((fop->seq.filename_list.size() > 1) &&
+        if ((fop->m_seq.filename_list.size() > 1) &&
             (ui::Alert::show("Notice"
               "<<Possible animation with:"
               "<<%s, %s..."
               "<<Do you want to load the sequence of bitmaps?"
               "||&Agree||&Skip",
-              base::get_file_name(fop->seq.filename_list[0]).c_str(),
-              base::get_file_name(fop->seq.filename_list[1]).c_str()) != 1)) {
+              base::get_file_name(fop->m_seq.filename_list[0]).c_str(),
+              base::get_file_name(fop->m_seq.filename_list[1]).c_str()) != 1)) {
 
           // If the user replies "Skip", we need just one file name
           // (the first one).
-          if (fop->seq.filename_list.size() > 1) {
-            fop->seq.filename_list.erase(fop->seq.filename_list.begin()+1,
-                                         fop->seq.filename_list.end());
+          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());
           }
         }
       }
     }
   }
   else
-    fop->filename = filename;
+    fop->m_filename = filename;
 
   /* load just one frame */
   if (flags & FILE_LOAD_ONE_FRAME)
-    fop->oneframe = true;
+    fop->m_oneframe = true;
 
 done:;
-  return fop;
+  return fop.release();
 }
 
-FileOp* fop_to_save_document(const Context* context, const Document* document,
-  const char* filename, const char* fn_format_arg)
+// static
+FileOp* FileOp::createSaveDocumentOperation(const Context* context,
+                                            const Document* document,
+                                            const char* filename,
+                                            const char* fn_format_arg)
 {
-  FileOp *fop;
-  bool fatal;
-
-  fop = fop_new(FileOpSave, const_cast<Context*>(context));
-  if (!fop)
-    return NULL;
+  base::UniquePtr<FileOp> fop(
+    new FileOp(FileOpSave, const_cast<Context*>(context)));
 
   // Document to save
-  fop->document = const_cast<Document*>(document);
+  fop->m_document = const_cast<Document*>(document);
 
   // Get the extension of the filename (in lower case)
   std::string extension = base::string_to_lower(base::get_file_extension(filename));
@@ -243,49 +234,49 @@ FileOp* fop_to_save_document(const Context* context, const Document* document,
   LOG("Saving document \"%s\" (%s)\n", filename, extension.c_str());
 
   // Get the format through the extension of the filename
-  fop->format = FileFormatsManager::instance()
+  fop->m_format = FileFormatsManager::instance()
     ->getFileFormatByExtension(extension.c_str());
 
-  if (!fop->format ||
-      !fop->format->support(FILE_SUPPORT_SAVE)) {
-    fop_error(fop, "ASEPRITE can't save \"%s\" files\n", extension.c_str());
-    return fop;
+  if (!fop->m_format ||
+      !fop->m_format->support(FILE_SUPPORT_SAVE)) {
+    fop->setError("ASEPRITE can't save \"%s\" files\n", extension.c_str());
+    return fop.release();
   }
 
   // Warnings
   std::string warnings;
-  fatal = false;
+  bool fatal = false;
 
   /* check image type support */
-  switch (fop->document->sprite()->pixelFormat()) {
+  switch (fop->m_document->sprite()->pixelFormat()) {
 
     case IMAGE_RGB:
-      if (!(fop->format->support(FILE_SUPPORT_RGB))) {
+      if (!(fop->m_format->support(FILE_SUPPORT_RGB))) {
         warnings += "<<- RGB format";
         fatal = true;
       }
 
-      if (!(fop->format->support(FILE_SUPPORT_RGBA)) &&
-          fop->document->sprite()->needAlpha()) {
+      if (!(fop->m_format->support(FILE_SUPPORT_RGBA)) &&
+          fop->m_document->sprite()->needAlpha()) {
 
         warnings += "<<- Alpha channel";
       }
       break;
 
     case IMAGE_GRAYSCALE:
-      if (!(fop->format->support(FILE_SUPPORT_GRAY))) {
+      if (!(fop->m_format->support(FILE_SUPPORT_GRAY))) {
         warnings += "<<- Grayscale format";
         fatal = true;
       }
-      if (!(fop->format->support(FILE_SUPPORT_GRAYA)) &&
-          fop->document->sprite()->needAlpha()) {
+      if (!(fop->m_format->support(FILE_SUPPORT_GRAYA)) &&
+          fop->m_document->sprite()->needAlpha()) {
 
         warnings += "<<- Alpha channel";
       }
       break;
 
     case IMAGE_INDEXED:
-      if (!(fop->format->support(FILE_SUPPORT_INDEXED))) {
+      if (!(fop->m_format->support(FILE_SUPPORT_INDEXED))) {
         warnings += "<<- Indexed format";
         fatal = true;
       }
@@ -293,38 +284,38 @@ FileOp* fop_to_save_document(const Context* context, const Document* document,
   }
 
   // Frames support
-  if (fop->document->sprite()->totalFrames() > 1) {
-    if (!fop->format->support(FILE_SUPPORT_FRAMES) &&
-        !fop->format->support(FILE_SUPPORT_SEQUENCES)) {
+  if (fop->m_document->sprite()->totalFrames() > 1) {
+    if (!fop->m_format->support(FILE_SUPPORT_FRAMES) &&
+        !fop->m_format->support(FILE_SUPPORT_SEQUENCES)) {
       warnings += "<<- Frames";
     }
   }
 
   // Layers support
-  if (fop->document->sprite()->folder()->getLayersCount() > 1) {
-    if (!(fop->format->support(FILE_SUPPORT_LAYERS))) {
+  if (fop->m_document->sprite()->folder()->getLayersCount() > 1) {
+    if (!(fop->m_format->support(FILE_SUPPORT_LAYERS))) {
       warnings += "<<- Layers";
     }
   }
 
   // Palettes support
-  if (fop->document->sprite()->getPalettes().size() > 1) {
-    if (!fop->format->support(FILE_SUPPORT_PALETTES) &&
-        !fop->format->support(FILE_SUPPORT_SEQUENCES)) {
+  if (fop->m_document->sprite()->getPalettes().size() > 1) {
+    if (!fop->m_format->support(FILE_SUPPORT_PALETTES) &&
+        !fop->m_format->support(FILE_SUPPORT_SEQUENCES)) {
       warnings += "<<- Palette changes between frames";
     }
   }
 
   // Check frames support
-  if (!fop->document->sprite()->frameTags().empty()) {
-    if (!fop->format->support(FILE_SUPPORT_FRAME_TAGS)) {
+  if (!fop->m_document->sprite()->frameTags().empty()) {
+    if (!fop->m_format->support(FILE_SUPPORT_FRAME_TAGS)) {
       warnings += "<<- Frame tags";
     }
   }
 
   // Big palettes
-  if (!fop->format->support(FILE_SUPPORT_BIG_PALETTES)) {
-    for (Palette* pal : fop->document->sprite()->getPalettes()) {
+  if (!fop->m_format->support(FILE_SUPPORT_BIG_PALETTES)) {
+    for (const Palette* pal : fop->m_document->sprite()->getPalettes()) {
       if (pal->size() > 256) {
         warnings += "<<- Palettes with more than 256 colors";
         break;
@@ -333,9 +324,9 @@ FileOp* fop_to_save_document(const Context* context, const Document* document,
   }
 
   // Palette with alpha
-  if (!fop->format->support(FILE_SUPPORT_PALETTE_WITH_ALPHA)) {
+  if (!fop->m_format->support(FILE_SUPPORT_PALETTE_WITH_ALPHA)) {
     bool done = false;
-    for (Palette* pal : fop->document->sprite()->getPalettes()) {
+    for (const Palette* pal : fop->m_document->sprite()->getPalettes()) {
       for (int c=0; c<pal->size(); ++c) {
         if (rgba_geta(pal->getEntry(c)) < 255) {
           warnings += "<<- Palette with alpha channel";
@@ -368,35 +359,33 @@ FileOp* fop_to_save_document(const Context* context, const Document* document,
         "<<Do you want continue with \".%s\" anyway?"
         "||%s",
         title.c_str(),
-        fop->format->name(),
+        fop->m_format->name(),
         warnings.c_str(),
-        fop->format->name(),
+        fop->m_format->name(),
         buttons.c_str());
 
       // Operation can't be done (by fatal error) or the user cancel
       // the operation
-      if ((fatal) || (ret != 1)) {
-        fop_free(fop);
-        return NULL;
-      }
+      if ((fatal) || (ret != 1))
+        return nullptr;
     }
     // No interactive & fatal error?
     else if (fatal) {
-      fop_error(fop, warnings.c_str());
-      return fop;
+      fop->setError(warnings.c_str());
+      return fop.release();
     }
   }
 
   // Use the "sequence" interface.
-  if (fop->format->support(FILE_SUPPORT_SEQUENCES)) {
-    fop_prepare_for_sequence(fop);
+  if (fop->m_format->support(FILE_SUPPORT_SEQUENCES)) {
+    fop->prepareForSequence();
 
     std::string fn = filename;
     std::string fn_format = fn_format_arg;
     bool default_format = false;
 
     if (fn_format.empty()) {
-      if (fop->document->sprite()->totalFrames() == 1)
+      if (fop->m_document->sprite()->totalFrames() == 1)
         fn_format = "{fullname}";
       else {
         fn_format = "{path}/{title}{frame}.{extension}";
@@ -405,12 +394,12 @@ FileOp* fop_to_save_document(const Context* context, const Document* document,
     }
 
     // Save one frame
-    if (fop->document->sprite()->totalFrames() == 1) {
+    if (fop->m_document->sprite()->totalFrames() == 1) {
       FilenameInfo fnInfo;
       fnInfo.filename(fn);
 
       fn = filename_formatter(fn_format, fnInfo);
-      fop->seq.filename_list.push_back(fn);
+      fop->m_seq.filename_list.push_back(fn);
     }
     // Save multiple frames
     else {
@@ -430,7 +419,7 @@ FileOp* fop_to_save_document(const Context* context, const Document* document,
         }
       }
 
-      Sprite* spr = fop->document->sprite();
+      Sprite* spr = fop->m_document->sprite();
       std::vector<char> buf(32);
       std::sprintf(&buf[0], "{frame%0*d}", width, 0);
       if (default_format)
@@ -451,98 +440,96 @@ FileOp* fop_to_save_document(const Context* context, const Document* document,
         std::string frame_fn =
           filename_formatter(fn_format, fnInfo);
 
-        fop->seq.filename_list.push_back(frame_fn);
+        fop->m_seq.filename_list.push_back(frame_fn);
       }
     }
   }
   else
-    fop->filename = filename;
+    fop->m_filename = filename;
 
   // Configure output format?
-  if (fop->format->support(FILE_SUPPORT_GET_FORMAT_OPTIONS)) {
-    base::SharedPtr<FormatOptions> format_options = fop->format->getFormatOptions(fop);
+  if (fop->m_format->support(FILE_SUPPORT_GET_FORMAT_OPTIONS)) {
+    base::SharedPtr<FormatOptions> format_options =
+      fop->m_format->getFormatOptions(fop);
 
     // Does the user cancelled the operation?
-    if (!format_options) {
-      fop_free(fop);
-      return NULL;
-    }
+    if (!format_options)
+      return nullptr;
 
-    fop->seq.format_options = format_options;
-    fop->document->setFormatOptions(format_options);
+    fop->m_seq.format_options = format_options;
+    fop->m_document->setFormatOptions(format_options);
   }
 
-  return fop;
+  return fop.release();
 }
 
 // Executes the file operation: loads or saves the sprite.
 //
 // It can be called from a different thread of the one used
-// by fop_to_load_sprite() or fop_to_save_sprite().
+// by FileOp::createLoadDocumentOperation() or createSaveDocumentOperation().
 //
-// After this function you must to mark the "fop" as "done" calling
-// fop_done() function.
-void fop_operate(FileOp *fop, IFileOpProgress* progress)
+// After this function you must to mark the FileOp as "done" calling
+// FileOp::done() function.
+void FileOp::operate(IFileOpProgress* progress)
 {
-  ASSERT(fop != NULL);
-  ASSERT(!fop_is_done(fop));
+  ASSERT(!isDone());
 
-  fop->progressInterface = progress;
+  m_progressInterface = progress;
 
   // Load //////////////////////////////////////////////////////////////////////
-  if (fop->type == FileOpLoad &&
-      fop->format != NULL &&
-      fop->format->support(FILE_SUPPORT_LOAD)) {
+  if (m_type == FileOpLoad &&
+      m_format != NULL &&
+      m_format->support(FILE_SUPPORT_LOAD)) {
     // Load a sequence
-    if (fop->is_sequence()) {
+    if (isSequence()) {
       // Default palette
-      fop->seq.palette->makeBlack();
+      m_seq.palette->makeBlack();
 
       // Load the sequence
-      frame_t frames(fop->seq.filename_list.size());
+      frame_t frames(m_seq.filename_list.size());
       frame_t frame(0);
       Image* old_image = nullptr;
 
       // TODO set_palette for each frame???
       auto add_image = [&]() {
-        fop->seq.last_cel->data()->setImage(fop->seq.image);
-        fop->seq.layer->addCel(fop->seq.last_cel);
+        m_seq.last_cel->data()->setImage(m_seq.image);
+        m_seq.layer->addCel(m_seq.last_cel);
 
-        if (fop->document->sprite()->palette(frame)
-            ->countDiff(fop->seq.palette, NULL, NULL) > 0) {
-          fop->seq.palette->setFrame(frame);
-          fop->document->sprite()->setPalette(fop->seq.palette, true);
+        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);
         }
 
-        old_image = fop->seq.image.get();
-        fop->seq.image.reset(NULL);
-        fop->seq.last_cel = NULL;
+        old_image = m_seq.image.get();
+        m_seq.image.reset(NULL);
+        m_seq.last_cel = NULL;
       };
 
-      fop->seq.has_alpha = false;
-      fop->seq.progress_offset = 0.0f;
-      fop->seq.progress_fraction = 1.0f / (double)frames;
+      m_seq.has_alpha = false;
+      m_seq.progress_offset = 0.0f;
+      m_seq.progress_fraction = 1.0f / (double)frames;
 
-      std::vector<std::string>::iterator it = fop->seq.filename_list.begin();
-      std::vector<std::string>::iterator end = fop->seq.filename_list.end();
+      auto it = m_seq.filename_list.begin(),
+           end = m_seq.filename_list.end();
       for (; it != end; ++it) {
-        fop->filename = it->c_str();
+        m_filename = it->c_str();
 
         // Call the "load" procedure to read the first bitmap.
-        bool loadres = fop->format->load(fop);
+        bool loadres = m_format->load(this);
         if (!loadres) {
-          fop_error(fop, "Error loading frame %d from file \"%s\"\n",
-                    frame+1, fop->filename.c_str());
+          setError("Error loading frame %d from file \"%s\"\n",
+                   frame+1, m_filename.c_str());
         }
 
         // For the first frame...
         if (!old_image) {
           // Error reading the first frame
-          if (!loadres || !fop->document || !fop->seq.last_cel) {
-            fop->seq.image.reset();
-            delete fop->seq.last_cel;
-            delete fop->document;
-            fop->document = nullptr;
+          if (!loadres || !m_document || !m_seq.last_cel) {
+            m_seq.image.reset();
+            delete m_seq.last_cel;
+            delete m_document;
+            m_document = nullptr;
             break;
           }
           // Read ok
@@ -554,27 +541,27 @@ void fop_operate(FileOp *fop, IFileOpProgress* progress)
         // For other frames
         else {
           // All done (or maybe not enough memory)
-          if (!loadres || !fop->seq.last_cel) {
-            fop->seq.image.reset();
-            delete fop->seq.last_cel;
+          if (!loadres || !m_seq.last_cel) {
+            m_seq.image.reset();
+            delete m_seq.last_cel;
             break;
           }
 
           // Compare the old frame with the new one
 #if USE_LINK // TODO this should be configurable through a check-box
-          if (count_diff_between_images(old_image, fop->seq.image)) {
+          if (count_diff_between_images(old_image, m_seq.image)) {
             add_image();
           }
           // We don't need this image
           else {
-            delete fop->seq.image;
+            delete m_seq.image;
 
             // But add a link frame
-            fop->seq.last_cel->image = image_index;
-            layer_add_frame(fop->seq.layer, fop->seq.last_cel);
+            m_seq.last_cel->image = image_index;
+            layer_add_frame(m_seq.layer, m_seq.last_cel);
 
-            fop->seq.last_image = NULL;
-            fop->seq.last_cel = NULL;
+            m_seq.last_image = NULL;
+            m_seq.last_cel = NULL;
           }
 #else
           add_image();
@@ -582,153 +569,146 @@ void fop_operate(FileOp *fop, IFileOpProgress* progress)
         }
 
         ++frame;
-        fop->seq.progress_offset += fop->seq.progress_fraction;
+        m_seq.progress_offset += m_seq.progress_fraction;
       }
-      fop->filename = *fop->seq.filename_list.begin();
+      m_filename = *m_seq.filename_list.begin();
 
       // Final setup
-      if (fop->document != NULL) {
+      if (m_document != NULL) {
         // Configure the layer as the 'Background'
-        if (!fop->seq.has_alpha)
-          fop->seq.layer->configureAsBackground();
+        if (!m_seq.has_alpha)
+          m_seq.layer->configureAsBackground();
 
         // Set the frames range
-        fop->document->sprite()->setTotalFrames(frame);
+        m_document->sprite()->setTotalFrames(frame);
 
         // Sets special options from the specific format (e.g. BMP
         // file can contain the number of bits per pixel).
-        fop->document->setFormatOptions(fop->seq.format_options);
+        m_document->setFormatOptions(m_seq.format_options);
       }
     }
     // Direct load from one file.
     else {
       // Call the "load" procedure.
-      if (!fop->format->load(fop))
-        fop_error(fop, "Error loading sprite from file \"%s\"\n",
-                  fop->filename.c_str());
+      if (!m_format->load(this))
+        setError("Error loading sprite from file \"%s\"\n",
+                 m_filename.c_str());
     }
   }
   // Save //////////////////////////////////////////////////////////////////////
-  else if (fop->type == FileOpSave &&
-           fop->format != NULL &&
-           fop->format->support(FILE_SUPPORT_SAVE)) {
+  else if (m_type == FileOpSave &&
+           m_format != NULL &&
+           m_format->support(FILE_SUPPORT_SAVE)) {
 #ifdef ENABLE_SAVE
     // Save a sequence
-    if (fop->is_sequence()) {
-      ASSERT(fop->format->support(FILE_SUPPORT_SEQUENCES));
+    if (isSequence()) {
+      ASSERT(m_format->support(FILE_SUPPORT_SEQUENCES));
 
-      Sprite* sprite = fop->document->sprite();
+      Sprite* sprite = m_document->sprite();
 
       // Create a temporary bitmap
-      fop->seq.image.reset(Image::create(sprite->pixelFormat(),
+      m_seq.image.reset(Image::create(sprite->pixelFormat(),
           sprite->width(),
           sprite->height()));
 
-      fop->seq.progress_offset = 0.0f;
-      fop->seq.progress_fraction = 1.0f / (double)sprite->totalFrames();
+      m_seq.progress_offset = 0.0f;
+      m_seq.progress_fraction = 1.0f / (double)sprite->totalFrames();
 
       // For each frame in the sprite.
       render::Render render;
       for (frame_t frame(0); frame < sprite->totalFrames(); ++frame) {
-        // Draw the "frame" in "fop->seq.image"
-        render.renderSprite(fop->seq.image.get(), sprite, frame);
+        // Draw the "frame" in "m_seq.image"
+        render.renderSprite(m_seq.image.get(), sprite, frame);
 
         // Setup the palette.
-        sprite->palette(frame)->copyColorsTo(fop->seq.palette);
+        sprite->palette(frame)->copyColorsTo(m_seq.palette);
 
         // Setup the filename to be used.
-        fop->filename = fop->seq.filename_list[frame];
+        m_filename = m_seq.filename_list[frame];
 
         // Call the "save" procedure... did it fail?
-        if (!fop->format->save(fop)) {
-          fop_error(fop, "Error saving frame %d in the file \"%s\"\n",
-            frame+1, fop->filename.c_str());
+        if (!m_format->save(this)) {
+          setError("Error saving frame %d in the file \"%s\"\n",
+                   frame+1, m_filename.c_str());
           break;
         }
 
-        fop->seq.progress_offset += fop->seq.progress_fraction;
+        m_seq.progress_offset += m_seq.progress_fraction;
       }
-      fop->filename = *fop->seq.filename_list.begin();
+      m_filename = *m_seq.filename_list.begin();
 
       // Destroy the image
-      fop->seq.image.reset(NULL);
+      m_seq.image.reset(NULL);
     }
     // Direct save to a file.
     else {
       // Call the "save" procedure.
-      if (!fop->format->save(fop))
-        fop_error(fop, "Error saving the sprite in the file \"%s\"\n",
-                  fop->filename.c_str());
+      if (!m_format->save(this))
+        setError("Error saving the sprite in the file \"%s\"\n",
+                 m_filename.c_str());
     }
 #else
-    fop_error(fop,
+    setError(
       "Save operation is not supported in trial version.\n"
       "Go to " WEBSITE_DOWNLOAD " and get the full-version.");
 #endif
   }
 
   // Progress = 100%
-  fop_progress(fop, 1.0f);
+  setProgress(1.0f);
 }
 
 // After mark the 'fop' as 'done' you must to free it calling fop_free().
-void fop_done(FileOp *fop)
+void FileOp::done()
 {
   // Finally done.
-  scoped_lock lock(*fop->mutex);
-  fop->done = true;
+  scoped_lock lock(m_mutex);
+  m_done = true;
 }
 
-void fop_stop(FileOp *fop)
+void FileOp::stop()
 {
-  scoped_lock lock(*fop->mutex);
-  if (!fop->done)
-    fop->stop = true;
+  scoped_lock lock(m_mutex);
+  if (!m_done)
+    m_stop = true;
 }
 
 FileOp::~FileOp()
 {
-  if (this->format)
-    this->format->destroyData(this);
+  if (m_format)
+    m_format->destroyData(this);
 
-  delete this->seq.palette;
-  delete this->mutex;
+  delete m_seq.palette;
 }
 
 void FileOp::createDocument(Sprite* spr)
 {
   // spr can be NULL if the sprite is set in onPostLoad() then
 
-  ASSERT(this->document == NULL);
-  this->document = new Document(spr);
-}
-
-void fop_free(FileOp *fop)
-{
-  delete fop;
+  ASSERT(m_document == NULL);
+  m_document = new Document(spr);
 }
 
-void fop_post_load(FileOp* fop)
+void FileOp::postLoad()
 {
-  if (fop->document == NULL)
+  if (m_document == NULL)
     return;
 
   // Set the filename.
-  if (fop->is_sequence())
-    fop->document->setFilename(fop->seq.filename_list.begin()->c_str());
+  if (isSequence())
+    m_document->setFilename(m_seq.filename_list.begin()->c_str());
   else
-    fop->document->setFilename(fop->filename.c_str());
+    m_document->setFilename(m_filename.c_str());
 
-  bool result = fop->format->postLoad(fop);
+  bool result = m_format->postLoad(this);
   if (!result) {
     // Destroy the document
-    delete fop->document;
-    fop->document = NULL;
-
+    delete m_document;
+    m_document = nullptr;
     return;
   }
 
-  Sprite* sprite = fop->document->sprite();
+  Sprite* sprite = m_document->sprite();
   if (sprite) {
     // Creates a suitable palette for RGB images
     if (sprite->pixelFormat() == IMAGE_RGB &&
@@ -744,37 +724,42 @@ void fop_post_load(FileOp* fop)
     }
   }
 
-  fop->document->markAsSaved();
+  m_document->markAsSaved();
+}
+
+base::SharedPtr<FormatOptions> FileOp::sequenceGetFormatOptions() const
+{
+  return m_seq.format_options;
 }
 
-void fop_sequence_set_format_options(FileOp* fop, const base::SharedPtr<FormatOptions>& format_options)
+void FileOp::sequenceSetFormatOptions(const base::SharedPtr<FormatOptions>& format_options)
 {
-  ASSERT(!fop->seq.format_options);
-  fop->seq.format_options = format_options;
+  ASSERT(!m_seq.format_options);
+  m_seq.format_options = format_options;
 }
 
-void fop_sequence_set_ncolors(FileOp* fop, int ncolors)
+void FileOp::sequenceSetNColors(int ncolors)
 {
-  fop->seq.palette->resize(ncolors);
+  m_seq.palette->resize(ncolors);
 }
 
-int fop_sequence_get_ncolors(FileOp* fop)
+int FileOp::sequenceGetNColors() const
 {
-  return fop->seq.palette->size();
+  return m_seq.palette->size();
 }
 
-void fop_sequence_set_color(FileOp *fop, int index, int r, int g, int b)
+void FileOp::sequenceSetColor(int index, int r, int g, int b)
 {
-  fop->seq.palette->setEntry(index, rgba(r, g, b, 255));
+  m_seq.palette->setEntry(index, rgba(r, g, b, 255));
 }
 
-void fop_sequence_get_color(FileOp *fop, int index, int *r, int *g, int *b)
+void FileOp::sequenceGetColor(int index, int* r, int* g, int* b) const
 {
   uint32_t c;
 
   ASSERT(index >= 0);
-  if (index >= 0 && index < fop->seq.palette->size())
-    c = fop->seq.palette->getEntry(index);
+  if (index >= 0 && index < m_seq.palette->size())
+    c = m_seq.palette->getEntry(index);
   else
     c = rgba(0, 0, 0, 255);     // Black color
 
@@ -783,31 +768,31 @@ void fop_sequence_get_color(FileOp *fop, int index, int *r, int *g, int *b)
   *b = rgba_getb(c);
 }
 
-void fop_sequence_set_alpha(FileOp* fop, int index, int a)
+void FileOp::sequenceSetAlpha(int index, int a)
 {
-  int c = fop->seq.palette->getEntry(index);
+  int c = m_seq.palette->getEntry(index);
   int r = rgba_getr(c);
   int g = rgba_getg(c);
   int b = rgba_getb(c);
 
-  fop->seq.palette->setEntry(index, rgba(r, g, b, a));
+  m_seq.palette->setEntry(index, rgba(r, g, b, a));
 }
 
-void fop_sequence_get_alpha(FileOp* fop, int index, int* a)
+void FileOp::sequenceGetAlpha(int index, int* a) const
 {
   ASSERT(index >= 0);
-  if (index >= 0 && index < fop->seq.palette->size())
-    *a = rgba_geta(fop->seq.palette->getEntry(index));
+  if (index >= 0 && index < m_seq.palette->size())
+    *a = rgba_geta(m_seq.palette->getEntry(index));
   else
     *a = 0;
 }
 
-Image* fop_sequence_image(FileOp* fop, PixelFormat pixelFormat, int w, int h)
+Image* FileOp::sequenceImage(PixelFormat pixelFormat, int w, int h)
 {
   Sprite* sprite;
 
   // Create the image
-  if (!fop->document) {
+  if (!m_document) {
     sprite = new Sprite(pixelFormat, w, h, 256);
     try {
       LayerImage* layer = new LayerImage(sprite);
@@ -816,8 +801,8 @@ Image* fop_sequence_image(FileOp* fop, PixelFormat pixelFormat, int w, int h)
       sprite->folder()->addLayer(layer);
 
       // Done
-      fop->createDocument(sprite);
-      fop->seq.layer = layer;
+      createDocument(sprite);
+      m_seq.layer = layer;
     }
     catch (...) {
       delete sprite;
@@ -825,25 +810,25 @@ Image* fop_sequence_image(FileOp* fop, PixelFormat pixelFormat, int w, int h)
     }
   }
   else {
-    sprite = fop->document->sprite();
+    sprite = m_document->sprite();
 
     if (sprite->pixelFormat() != pixelFormat)
-      return NULL;
+      return nullptr;
   }
 
-  if (fop->seq.last_cel) {
-    fop_error(fop, "Error: called two times \"fop_sequence_image()\".\n");
-    return NULL;
+  if (m_seq.last_cel) {
+    setError("Error: called two times \"fop_sequence_image()\".\n");
+    return nullptr;
   }
 
   // Create a bitmap
-  fop->seq.image.reset(Image::create(pixelFormat, w, h));
-  fop->seq.last_cel = new Cel(fop->seq.frame++, ImageRef(NULL));
+  m_seq.image.reset(Image::create(pixelFormat, w, h));
+  m_seq.last_cel = new Cel(m_seq.frame++, ImageRef(nullptr));
 
-  return fop->seq.image.get();
+  return m_seq.image.get();
 }
 
-void fop_error(FileOp *fop, const char *format, ...)
+void FileOp::setError(const char *format, ...)
 {
   char buf_error[4096];
   va_list ap;
@@ -853,92 +838,84 @@ void fop_error(FileOp *fop, const char *format, ...)
 
   // Concatenate the new error
   {
-    scoped_lock lock(*fop->mutex);
-    fop->error += buf_error;
+    scoped_lock lock(m_mutex);
+    m_error += buf_error;
   }
 }
 
-void fop_progress(FileOp *fop, double progress)
+void FileOp::setProgress(double progress)
 {
-  scoped_lock lock(*fop->mutex);
+  scoped_lock lock(m_mutex);
 
-  if (fop->is_sequence()) {
-    fop->progress =
-      fop->seq.progress_offset +
-      fop->seq.progress_fraction*progress;
+  if (isSequence()) {
+    m_progress =
+      m_seq.progress_offset +
+      m_seq.progress_fraction*progress;
   }
   else {
-    fop->progress = progress;
+    m_progress = progress;
   }
 
-  if (fop->progressInterface)
-    fop->progressInterface->ackFileOpProgress(progress);
+  if (m_progressInterface)
+    m_progressInterface->ackFileOpProgress(progress);
 }
 
-double fop_get_progress(FileOp *fop)
+double FileOp::progress() const
 {
   double progress;
   {
-    scoped_lock lock(*fop->mutex);
-    progress = fop->progress;
+    scoped_lock lock(m_mutex);
+    progress = m_progress;
   }
   return progress;
 }
 
-// Returns true when the file operation finished, this means, when the
-// fop_operate() routine ends.
-bool fop_is_done(FileOp *fop)
+// Returns true when the file operation has finished, this means, when
+// the FileOp::operate() routine ends.
+bool FileOp::isDone() const
 {
   bool done;
   {
-    scoped_lock lock(*fop->mutex);
-    done = fop->done;
+    scoped_lock lock(m_mutex);
+    done = m_done;
   }
   return done;
 }
 
-bool fop_is_stop(FileOp *fop)
+bool FileOp::isStop() const
 {
   bool stop;
   {
-    scoped_lock lock(*fop->mutex);
-    stop = fop->stop;
+    scoped_lock lock(m_mutex);
+    stop = m_stop;
   }
   return stop;
 }
 
-static FileOp* fop_new(FileOpType type, Context* context)
+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)
 {
-  FileOp* fop = new FileOp;
-
-  fop->type = type;
-  fop->format = NULL;
-  fop->format_data = NULL;
-  fop->context = context;
-  fop->document = NULL;
-
-  fop->mutex = new base::mutex();
-  fop->progress = 0.0f;
-  fop->progressInterface = NULL;
-  fop->done = false;
-  fop->stop = false;
-  fop->oneframe = false;
-
-  fop->seq.palette = NULL;
-  fop->seq.image.reset(NULL);
-  fop->seq.progress_offset = 0.0f;
-  fop->seq.progress_fraction = 0.0f;
-  fop->seq.frame = frame_t(0);
-  fop->seq.layer = NULL;
-  fop->seq.last_cel = NULL;
-
-  return fop;
+  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;
 }
 
-static void fop_prepare_for_sequence(FileOp* fop)
+void FileOp::prepareForSequence()
 {
-  fop->seq.palette = new Palette(frame_t(0), 256);
-  fop->seq.format_options.reset();
+  m_seq.palette = new Palette(frame_t(0), 256);
+  m_seq.format_options.reset();
 }
 
 } // namespace app
diff --git a/src/app/file/file.h b/src/app/file/file.h
index 8e5babf..432fcd8 100644
--- a/src/app/file/file.h
+++ b/src/app/file/file.h
@@ -9,6 +9,7 @@
 #define APP_FILE_FILE_H_INCLUDED
 #pragma once
 
+#include "base/mutex.h"
 #include "base/shared_ptr.h"
 #include "doc/frame.h"
 #include "doc/image_ref.h"
@@ -23,10 +24,6 @@
 #define FILE_LOAD_SEQUENCE_YES          0x00000004
 #define FILE_LOAD_ONE_FRAME             0x00000008
 
-namespace base {
-  class mutex;
-}
-
 namespace doc {
   class Document;
 }
@@ -62,24 +59,84 @@ namespace app {
   };
 
   // Structure to load & save files.
-  struct FileOp {
-    FileOpType type;              // Operation type: 0=load, 1=save.
-    FileFormat* format;
-    void* format_data;            // Custom data for the FileFormat::onLoad/onSave operations.
-    Context* context;
-    Document* document;           // Loaded document, or document to be saved.
-    std::string filename;         // File-name to load/save.
+  class FileOp {
+  public:
+    static FileOp* createLoadDocumentOperation(Context* context, const char* filename, int flags);
+    static FileOp* createSaveDocumentOperation(const Context* context, const Document* document, const char* filename, const char* fn_format);
+
+    ~FileOp();
+
+    bool isSequence() const { return !m_seq.filename_list.empty(); }
+    bool isOneFrame() const { return m_oneframe; }
+
+    const std::string& filename() const { return m_filename; }
+    Context* context() const { return m_context; }
+    Document* document() const { return m_document; }
+    Document* releaseDocument() {
+      Document* doc = m_document;
+      m_document = nullptr;
+      return doc;
+    }
+
+    void createDocument(Sprite* spr);
+    void operate(IFileOpProgress* progress = nullptr);
+
+    void done();
+    void stop();
+    bool isDone() const;
+    bool isStop() const;
+
+    // Does extra post-load processing which may require user intervention.
+    void postLoad();
+
+    // Helpers for file decoder/encoder (FileFormat) with
+    // FILE_SUPPORT_SEQUENCES flag.
+    base::SharedPtr<FormatOptions> sequenceGetFormatOptions() const;
+    void sequenceSetFormatOptions(const base::SharedPtr<FormatOptions>& formatOptions);
+    void sequenceSetNColors(int ncolors);
+    int sequenceGetNColors() const;
+    void sequenceSetColor(int index, int r, int g, int b);
+    void sequenceGetColor(int index, int* r, int* g, int* b) const;
+    void sequenceSetAlpha(int index, int a);
+    void sequenceGetAlpha(int index, int* a) const;
+    Image* sequenceImage(PixelFormat pixelFormat, int w, int h);
+    const Image* sequenceImage() const { return m_seq.image.get(); }
+    bool sequenceGetHasAlpha() const {
+      return m_seq.has_alpha;
+    }
+    void sequenceSetHasAlpha(bool hasAlpha) {
+      m_seq.has_alpha = hasAlpha;
+    }
+
+    const std::string& error() const { return m_error; }
+    void setError(const char *error, ...);
+    bool hasError() const { return !m_error.empty(); }
+
+    double progress() const;
+    void setProgress(double progress);
+
+  private:
+    FileOp();                   // Undefined
+    FileOp(FileOpType type, Context* context);
+
+    FileOpType m_type;          // Operation type: 0=load, 1=save.
+    FileFormat* m_format;
+    Context* m_context;
+    // TODO this should be a shared pointer (and we should remove
+    //      releaseDocument() member function)
+    Document* m_document;       // Loaded document, or document to be saved.
+    std::string m_filename;     // File-name to load/save.
 
     // Shared fields between threads.
-    base::mutex* mutex;           // Mutex to access to the next two fields.
-    double progress;              // Progress (1.0 is ready).
-    IFileOpProgress* progressInterface;
-    std::string error;            // Error string.
-    bool done;                    // True if the operation finished.
-    bool stop;                    // Force the break of the operation.
-    bool oneframe;                // Load just one frame (in formats
-                                  // that support animation like
-                                  // GIF/FLI/ASE).
+    mutable base::mutex m_mutex; // Mutex to access to the next two fields.
+    double m_progress;          // Progress (1.0 is ready).
+    IFileOpProgress* m_progressInterface;
+    std::string m_error;        // Error string.
+    bool m_done;                // True if the operation finished.
+    bool m_stop;                // Force the break of the operation.
+    bool m_oneframe;            // Load just one frame (in formats
+                                // that support animation like
+                                // GIF/FLI/ASE).
 
     // Data for sequences.
     struct {
@@ -95,19 +152,9 @@ namespace app {
       LayerImage* layer;
       Cel* last_cel;
       base::SharedPtr<FormatOptions> format_options;
-    } seq;
-
-    ~FileOp();
+    } m_seq;
 
-    bool has_error() const {
-      return !this->error.empty();
-    }
-
-    bool is_sequence() const {
-      return !this->seq.filename_list.empty();
-    }
-
-    void createDocument(Sprite* spr);
+    void prepareForSequence();
   };
 
   // Available extensions for each load/save operation.
@@ -120,34 +167,6 @@ namespace app {
   app::Document* load_document(Context* context, const char* filename);
   int save_document(Context* context, doc::Document* document);
 
-  // Low-level routines to load/save documents.
-
-  FileOp* fop_to_load_document(Context* context, const char* filename, int flags);
-  FileOp* fop_to_save_document(const Context* context, const Document* document, const char* filename, const char* fn_format);
-  void fop_operate(FileOp* fop, IFileOpProgress* progress);
-  void fop_done(FileOp* fop);
-  void fop_stop(FileOp* fop);
-  void fop_free(FileOp* fop);
-
-  // Does extra post-load processing which may require user intervention.
-  void fop_post_load(FileOp* fop);
-
-  void fop_sequence_set_format_options(FileOp* fop, const base::SharedPtr<FormatOptions>& format_options);
-  void fop_sequence_set_ncolors(FileOp* fop, int ncolors);
-  int fop_sequence_get_ncolors(FileOp* fop);
-  void fop_sequence_set_color(FileOp* fop, int index, int r, int g, int b);
-  void fop_sequence_get_color(FileOp* fop, int index, int *r, int *g, int *b);
-  void fop_sequence_set_alpha(FileOp* fop, int index, int a);
-  void fop_sequence_get_alpha(FileOp* fop, int index, int* a);
-  Image* fop_sequence_image(FileOp* fi, PixelFormat pixelFormat, int w, int h);
-
-  void fop_error(FileOp* fop, const char *error, ...);
-  void fop_progress(FileOp* fop, double progress);
-
-  double fop_get_progress(FileOp* fop);
-  bool fop_is_done(FileOp* fop);
-  bool fop_is_stop(FileOp* fop);
-
 } // namespace app
 
 #endif
diff --git a/src/app/file/file_format.h b/src/app/file/file_format.h
index e6f1790..ed5d774 100644
--- a/src/app/file/file_format.h
+++ b/src/app/file/file_format.h
@@ -33,7 +33,7 @@ namespace app {
 
   class FormatOptions;
   class FileFormat;
-  struct FileOp;
+  class FileOp;
 
   // A file format supported by ASE. It is the base class to extend if
   // you want to add support to load and/or save a new kind of
diff --git a/src/app/file/fli_format.cpp b/src/app/file/fli_format.cpp
index 919eb77..3631b02 100644
--- a/src/app/file/fli_format.cpp
+++ b/src/app/file/fli_format.cpp
@@ -51,14 +51,14 @@ FileFormat* CreateFliFormat()
 bool FliFormat::onLoad(FileOp* fop)
 {
   // Open the file to read in binary mode
-  FileHandle handle(open_file_with_exception(fop->filename, "rb"));
+  FileHandle handle(open_file_with_exception(fop->filename(), "rb"));
   FILE* f = handle.get();
   flic::StdioFileInterface finterface(f);
   flic::Decoder decoder(&finterface);
 
   flic::Header header;
   if (!decoder.readHeader(header)) {
-    fop_error(fop, "The file doesn't have a FLIC header\n");
+    fop->setError("The file doesn't have a FLIC header\n");
     return false;
   }
 
@@ -92,7 +92,7 @@ bool FliFormat::onLoad(FileOp* fop)
        ++frame_in) {
     // Read the frame
     if (!decoder.readFrame(fliFrame)) {
-      fop_error(fop, "Error reading frame %d\n", frame_in);
+      fop->setError("Error reading frame %d\n", frame_in);
       continue;
     }
 
@@ -138,12 +138,12 @@ bool FliFormat::onLoad(FileOp* fop)
     }
 
     if (header.frames > 0)
-      fop_progress(fop, (float)(frame_in+1) / (float)(header.frames));
+      fop->setProgress((float)(frame_in+1) / (float)(header.frames));
 
-    if (fop_is_stop(fop))
+    if (fop->isStop())
       break;
 
-    if (fop->oneframe)
+    if (fop->isOneFrame())
       break;
   }
 
@@ -156,7 +156,7 @@ bool FliFormat::onLoad(FileOp* fop)
 
 #ifdef ENABLE_SAVE
 
-static int get_time_precision(Sprite *sprite)
+static int get_time_precision(const Sprite *sprite)
 {
   // Check if all frames have the same duration
   bool constantFrameRate = true;
@@ -180,10 +180,10 @@ static int get_time_precision(Sprite *sprite)
 
 bool FliFormat::onSave(FileOp* fop)
 {
-  Sprite* sprite = fop->document->sprite();
+  const Sprite* sprite = fop->document()->sprite();
 
   // Open the file to write in binary mode
-  FileHandle handle(open_file_with_exception(fop->filename, "wb"));
+  FileHandle handle(open_file_with_exception(fop->filename(), "wb"));
   FILE* f = handle.get();
   flic::StdioFileInterface finterface(f);
   flic::Encoder encoder(&finterface);
@@ -233,12 +233,12 @@ bool FliFormat::onSave(FileOp* fop)
     }
 
     // Update progress
-    fop_progress(fop, (float)(frame_it+1) / (float)(sprite->totalFrames()+1));
+    fop->setProgress((float)(frame_it+1) / (float)(sprite->totalFrames()+1));
   }
 
   return true;
 }
 
-#endif
+#endif  // ENABLE_SAVE
 
 } // namespace app
diff --git a/src/app/file/gif_format.cpp b/src/app/file/gif_format.cpp
index f47facd..6d95951 100644
--- a/src/app/file/gif_format.cpp
+++ b/src/app/file/gif_format.cpp
@@ -212,15 +212,15 @@ public:
       readRecord(recType);
 
       // Just one frame?
-      if (m_fop->oneframe && m_frameNum > 0)
+      if (m_fop->isOneFrame() && m_frameNum > 0)
         break;
 
-      if (fop_is_stop(m_fop))
+      if (m_fop->isStop())
         break;
 
       if (m_filesize > 0) {
         int pos = posix_lseek(m_fd, 0, SEEK_CUR);
-        fop_progress(m_fop, double(pos) / double(m_filesize));
+        m_fop->setProgress(double(pos) / double(m_filesize));
       }
     }
 
@@ -785,12 +785,12 @@ bool GifFormat::onLoad(FileOp* fop)
 {
   // The filesize is used only to report some progress when we decode
   // the GIF file.
-  int filesize = base::file_size(fop->filename);
+  int filesize = base::file_size(fop->filename());
 
 #if GIFLIB_MAJOR >= 5
   int errCode = 0;
 #endif
-  int fd = open_file_descriptor_with_exception(fop->filename, "rb");
+  int fd = open_file_descriptor_with_exception(fop->filename(), "rb");
   GifFilePtr gif_file(DGifOpenFileHandle(fd
 #if GIFLIB_MAJOR >= 5
                                          , &errCode
@@ -798,7 +798,7 @@ bool GifFormat::onLoad(FileOp* fop)
                                          ), &DGifCloseFile);
 
   if (!gif_file) {
-    fop_error(fop, "Error loading GIF header.\n");
+    fop->setError("Error loading GIF header.\n");
     return false;
   }
 
@@ -818,7 +818,7 @@ public:
   GifEncoder(FileOp* fop, GifFileType* gifFile)
     : m_fop(fop)
     , m_gifFile(gifFile)
-    , m_sprite(fop->document->sprite())
+    , m_sprite(fop->document()->sprite())
     , m_spriteBounds(m_sprite->bounds())
     , m_hasBackground(m_sprite->backgroundLayer() ? true: false)
     , m_bitsPerPixel(1)
@@ -849,7 +849,7 @@ public:
     else
       m_clearColor = rgba(0, 0, 0, 0);
 
-    base::SharedPtr<GifOptions> gifOptions = fop->seq.format_options;
+    const base::SharedPtr<GifOptions> gifOptions = fop->sequenceGetFormatOptions();
     m_interlaced = gifOptions->interlaced();
     m_loop = (gifOptions->loop() ? 0: -1);
 
@@ -905,7 +905,7 @@ public:
                               frameBounds,
                               m_clearColor);
 
-      fop_progress(m_fop, double(frameNum+1) / double(nframes));
+      m_fop->setProgress(double(frameNum+1) / double(nframes));
     }
     return true;
   }
@@ -1240,7 +1240,7 @@ private:
 
   FileOp* m_fop;
   GifFileType* m_gifFile;
-  Sprite* m_sprite;
+  const Sprite* m_sprite;
   gfx::Rect m_spriteBounds;
   bool m_hasBackground;
   int m_bgIndex;
@@ -1262,7 +1262,7 @@ bool GifFormat::onSave(FileOp* fop)
 #if GIFLIB_MAJOR >= 5
   int errCode = 0;
 #endif
-  GifFilePtr gif_file(EGifOpenFileHandle(open_file_descriptor_with_exception(fop->filename, "wb")
+  GifFilePtr gif_file(EGifOpenFileHandle(open_file_descriptor_with_exception(fop->filename(), "wb")
 #if GIFLIB_MAJOR >= 5
                                          , &errCode
 #endif
@@ -1280,14 +1280,15 @@ bool GifFormat::onSave(FileOp* fop)
 base::SharedPtr<FormatOptions> GifFormat::onGetFormatOptions(FileOp* fop)
 {
   base::SharedPtr<GifOptions> gif_options;
-  if (fop->document->getFormatOptions())
-    gif_options = base::SharedPtr<GifOptions>(fop->document->getFormatOptions());
+  if (fop->document()->getFormatOptions())
+    gif_options = base::SharedPtr<GifOptions>(fop->document()->getFormatOptions());
 
   if (!gif_options)
     gif_options.reset(new GifOptions);
 
   // Non-interactive mode
-  if (!fop->context || !fop->context->isUIAvailable())
+  if (!fop->context() ||
+      !fop->context()->isUIAvailable())
     return gif_options;
 
   try {
diff --git a/src/app/file/ico_format.cpp b/src/app/file/ico_format.cpp
index db66ff0..320233a 100644
--- a/src/app/file/ico_format.cpp
+++ b/src/app/file/ico_format.cpp
@@ -80,7 +80,7 @@ struct BITMAPINFOHEADER {
 
 bool IcoFormat::onLoad(FileOp* fop)
 {
-  FileHandle handle(open_file_with_exception(fop->filename, "rb"));
+  FileHandle handle(open_file_with_exception(fop->filename(), "rb"));
   FILE* f = handle.get();
 
   // Read the icon header
@@ -90,12 +90,12 @@ bool IcoFormat::onLoad(FileOp* fop)
   header.entries  = fgetw(f);                   // Number of icons
 
   if (header.type != 1) {
-    fop_error(fop, "Invalid ICO file type.\n");
+    fop->setError("Invalid ICO file type.\n");
     return false;
   }
 
   if (header.entries < 1) {
-    fop_error(fop, "This ICO files does not contain images.\n");
+    fop->setError("This ICO files does not contain images.\n");
     return false;
   }
 
@@ -227,13 +227,13 @@ bool IcoFormat::onLoad(FileOp* fop)
 #ifdef ENABLE_SAVE
 bool IcoFormat::onSave(FileOp* fop)
 {
-  Sprite* sprite = fop->document->sprite();
+  const Sprite* sprite = fop->document()->sprite();
   int bpp, bw, bitsw;
   int size, offset, i;
   int c, x, y, b, m, v;
   frame_t n, num = sprite->totalFrames();
 
-  FileHandle handle(open_file_with_exception(fop->filename, "wb"));
+  FileHandle handle(open_file_with_exception(fop->filename(), "wb"));
   FILE* f = handle.get();
 
   offset = 6 + num*16;  // ICONDIR + ICONDIRENTRYs
diff --git a/src/app/file/jpeg_format.cpp b/src/app/file/jpeg_format.cpp
index 6f968f1..cb6622c 100644
--- a/src/app/file/jpeg_format.cpp
+++ b/src/app/file/jpeg_format.cpp
@@ -92,7 +92,7 @@ static void output_message(j_common_ptr cinfo)
   LOG("JPEG library: \"%s\"\n", buffer);
 
   // Leave the message for the application.
-  fop_error(((struct error_mgr *)cinfo->err)->fop, "%s\n", buffer);
+  ((struct error_mgr *)cinfo->err)->fop->setError("%s\n", buffer);
 }
 
 bool JpegFormat::onLoad(FileOp* fop)
@@ -104,7 +104,7 @@ bool JpegFormat::onLoad(FileOp* fop)
   JDIMENSION buffer_height;
   int c;
 
-  FileHandle handle(open_file_with_exception(fop->filename, "rb"));
+  FileHandle handle(open_file_with_exception(fop->filename(), "rb"));
   FILE* file = handle.get();
 
   // Initialize the JPEG decompression object with error handling.
@@ -137,11 +137,11 @@ bool JpegFormat::onLoad(FileOp* fop)
   jpeg_start_decompress(&cinfo);
 
   // Create the image.
-  Image* image = fop_sequence_image(fop,
-                                    (cinfo.out_color_space == JCS_RGB ? IMAGE_RGB:
-                                                                        IMAGE_GRAYSCALE),
-                                    cinfo.output_width,
-                                    cinfo.output_height);
+  Image* image = fop->sequenceImage(
+    (cinfo.out_color_space == JCS_RGB ? IMAGE_RGB:
+                                        IMAGE_GRAYSCALE),
+    cinfo.output_width,
+    cinfo.output_height);
   if (!image) {
     jpeg_destroy_decompress(&cinfo);
     return false;
@@ -170,7 +170,7 @@ bool JpegFormat::onLoad(FileOp* fop)
   // Generate a grayscale palette if is necessary.
   if (image->pixelFormat() == IMAGE_GRAYSCALE)
     for (c=0; c<256; c++)
-      fop_sequence_set_color(fop, c, c, c, c);
+      fop->sequenceSetColor(c, c, c, c);
 
   // Read each scan line.
   while (cinfo.output_scanline < cinfo.output_height) {
@@ -213,8 +213,8 @@ bool JpegFormat::onLoad(FileOp* fop)
       }
     }
 
-    fop_progress(fop, (float)(cinfo.output_scanline+1) / (float)(cinfo.output_height));
-    if (fop_is_stop(fop))
+    fop->setProgress((float)(cinfo.output_scanline+1) / (float)(cinfo.output_height));
+    if (fop->isStop())
       break;
   }
 
@@ -234,14 +234,15 @@ bool JpegFormat::onSave(FileOp* fop)
 {
   struct jpeg_compress_struct cinfo;
   struct error_mgr jerr;
-  Image* image = fop->seq.image.get();
+  const Image* image = fop->sequenceImage();
   JSAMPARRAY buffer;
   JDIMENSION buffer_height;
-  base::SharedPtr<JpegOptions> jpeg_options = fop->seq.format_options;
+  const base::SharedPtr<JpegOptions> jpeg_options =
+    fop->sequenceGetFormatOptions();
   int c;
 
   // Open the file for write in it.
-  FileHandle handle(open_file_with_exception(fop->filename, "wb"));
+  FileHandle handle(open_file_with_exception(fop->filename(), "wb"));
   FILE* file = handle.get();
 
   // Allocate and initialize JPEG compression object.
@@ -277,7 +278,7 @@ bool JpegFormat::onSave(FileOp* fop)
   buffer_height = 1;
   buffer = (JSAMPARRAY)base_malloc(sizeof(JSAMPROW) * buffer_height);
   if (!buffer) {
-    fop_error(fop, "Not enough memory for the buffer.\n");
+    fop->setError("Not enough memory for the buffer.\n");
     jpeg_destroy_compress(&cinfo);
     return false;
   }
@@ -286,7 +287,7 @@ bool JpegFormat::onSave(FileOp* fop)
     buffer[c] = (JSAMPROW)base_malloc(sizeof(JSAMPLE) *
                                       cinfo.image_width * cinfo.num_components);
     if (!buffer[c]) {
-      fop_error(fop, "Not enough memory for buffer scanlines.\n");
+      fop->setError("Not enough memory for buffer scanlines.\n");
       for (c--; c>=0; c--)
         base_free(buffer[c]);
       base_free(buffer);
@@ -328,7 +329,7 @@ bool JpegFormat::onSave(FileOp* fop)
     }
     jpeg_write_scanlines(&cinfo, buffer, buffer_height);
 
-    fop_progress(fop, (float)(cinfo.next_scanline+1) / (float)(cinfo.image_height));
+    fop->setProgress((float)(cinfo.next_scanline+1) / (float)(cinfo.image_height));
   }
 
   // Destroy all data.
@@ -351,14 +352,15 @@ bool JpegFormat::onSave(FileOp* fop)
 base::SharedPtr<FormatOptions> JpegFormat::onGetFormatOptions(FileOp* fop)
 {
   base::SharedPtr<JpegOptions> jpeg_options;
-  if (fop->document->getFormatOptions())
-    jpeg_options = base::SharedPtr<JpegOptions>(fop->document->getFormatOptions());
+  if (fop->document()->getFormatOptions())
+    jpeg_options = base::SharedPtr<JpegOptions>(fop->document()->getFormatOptions());
 
   if (!jpeg_options)
     jpeg_options.reset(new JpegOptions);
 
   // Non-interactive mode
-  if (!fop->context || !fop->context->isUIAvailable())
+  if (!fop->context() ||
+      !fop->context()->isUIAvailable())
     return jpeg_options;
 
   try {
diff --git a/src/app/file/palette_file.cpp b/src/app/file/palette_file.cpp
index c092acc..6ebe2c0 100644
--- a/src/app/file/palette_file.cpp
+++ b/src/app/file/palette_file.cpp
@@ -62,22 +62,25 @@ Palette* load_palette(const char *filename)
   else {
     FileFormat* ff = FileFormatsManager::instance()->getFileFormatByExtension(ext.c_str());
     if (ff && ff->support(FILE_SUPPORT_LOAD)) {
-      FileOp* fop = fop_to_load_document(NULL, filename,
-        FILE_LOAD_SEQUENCE_NONE |
-        FILE_LOAD_ONE_FRAME);
-      if (fop && !fop->has_error()) {
-        fop_operate(fop, NULL);
-        fop_post_load(fop);
-
-        if (fop->document &&
-            fop->document->sprite() &&
-            fop->document->sprite()->palette(frame_t(0))) {
+      base::UniquePtr<FileOp> fop(
+        FileOp::createLoadDocumentOperation(
+          nullptr, filename,
+          FILE_LOAD_SEQUENCE_NONE |
+          FILE_LOAD_ONE_FRAME));
+
+      if (fop && !fop->hasError()) {
+        fop->operate(nullptr);
+        fop->postLoad();
+
+        if (fop->document() &&
+            fop->document()->sprite() &&
+            fop->document()->sprite()->palette(frame_t(0))) {
           pal = new Palette(
-            *fop->document->sprite()->palette(frame_t(0)));
+            *fop->document()->sprite()->palette(frame_t(0)));
         }
 
-        delete fop->document;
-        fop_done(fop);
+        delete fop->releaseDocument();
+        fop->done();
       }
     }
   }
diff --git a/src/app/file/pcx_format.cpp b/src/app/file/pcx_format.cpp
index 4a9eb28..0a5daa0 100644
--- a/src/app/file/pcx_format.cpp
+++ b/src/app/file/pcx_format.cpp
@@ -55,7 +55,7 @@ bool PcxFormat::onLoad(FileOp* fop)
   int x, y;
   char ch = 0;
 
-  FileHandle handle(open_file_with_exception(fop->filename, "rb"));
+  FileHandle handle(open_file_with_exception(fop->filename(), "rb"));
   FILE* f = handle.get();
 
   fgetc(f);                    /* skip manufacturer ID */
@@ -63,7 +63,7 @@ bool PcxFormat::onLoad(FileOp* fop)
   fgetc(f);                    /* skip encoding flag */
 
   if (fgetc(f) != 8) {         /* we like 8 bit color planes */
-    fop_error(fop, "This PCX doesn't have 8 bit color planes.\n");
+    fop->setError("This PCX doesn't have 8 bit color planes.\n");
     return false;
   }
 
@@ -78,7 +78,7 @@ bool PcxFormat::onLoad(FileOp* fop)
     r = fgetc(f);
     g = fgetc(f);
     b = fgetc(f);
-    fop_sequence_set_color(fop, c, r, g, b);
+    fop->sequenceSetColor(c, r, g, b);
   }
 
   fgetc(f);
@@ -93,9 +93,9 @@ bool PcxFormat::onLoad(FileOp* fop)
   for (c=0; c<60; c++)             /* skip some more junk */
     fgetc(f);
 
-  Image* image = fop_sequence_image(fop, bpp == 8 ?
-                                         IMAGE_INDEXED:
-                                         IMAGE_RGB,
+  Image* image = fop->sequenceImage(bpp == 8 ?
+                                    IMAGE_INDEXED:
+                                    IMAGE_RGB,
                                     width, height);
   if (!image) {
     return false;
@@ -146,12 +146,12 @@ bool PcxFormat::onLoad(FileOp* fop)
       }
     }
 
-    fop_progress(fop, (float)(y+1) / (float)(height));
-    if (fop_is_stop(fop))
+    fop->setProgress((float)(y+1) / (float)(height));
+    if (fop->isStop())
       break;
   }
 
-  if (!fop_is_stop(fop)) {
+  if (!fop->isStop()) {
     if (bpp == 8) {                  /* look for a 256 color palette */
       while ((c = fgetc(f)) != EOF) {
         if (c == 12) {
@@ -159,7 +159,7 @@ bool PcxFormat::onLoad(FileOp* fop)
             r = fgetc(f);
             g = fgetc(f);
             b = fgetc(f);
-            fop_sequence_set_color(fop, c, r, g, b);
+            fop->sequenceSetColor(c, r, g, b);
           }
           break;
         }
@@ -168,7 +168,7 @@ bool PcxFormat::onLoad(FileOp* fop)
   }
 
   if (ferror(f)) {
-    fop_error(fop, "Error reading file.\n");
+    fop->setError("Error reading file.\n");
     return false;
   }
   else {
@@ -179,7 +179,7 @@ bool PcxFormat::onLoad(FileOp* fop)
 #ifdef ENABLE_SAVE
 bool PcxFormat::onSave(FileOp* fop)
 {
-  Image* image = fop->seq.image.get();
+  const Image* image = fop->sequenceImage();
   int c, r, g, b;
   int x, y;
   int runcount;
@@ -187,7 +187,7 @@ bool PcxFormat::onSave(FileOp* fop)
   char runchar;
   char ch = 0;
 
-  FileHandle handle(open_file_with_exception(fop->filename, "wb"));
+  FileHandle handle(open_file_with_exception(fop->filename(), "wb"));
   FILE* f = handle.get();
 
   if (image->pixelFormat() == IMAGE_RGB) {
@@ -211,7 +211,7 @@ bool PcxFormat::onSave(FileOp* fop)
   fputw(200, f);                     /* VDpi */
 
   for (c=0; c<16; c++) {
-    fop_sequence_get_color(fop, c, &r, &g, &b);
+    fop->sequenceGetColor(c, &r, &g, &b);
     fputc(r, f);
     fputc(g, f);
     fputc(b, f);
@@ -274,14 +274,14 @@ bool PcxFormat::onSave(FileOp* fop)
 
     fputc(runchar, f);
 
-    fop_progress(fop, (float)(y+1) / (float)(image->height()));
+    fop->setProgress((float)(y+1) / (float)(image->height()));
   }
 
   if (depth == 8) {                      /* 256 color palette */
     fputc(12, f);
 
     for (c=0; c<256; c++) {
-      fop_sequence_get_color(fop, c, &r, &g, &b);
+      fop->sequenceGetColor(c, &r, &g, &b);
       fputc(r, f);
       fputc(g, f);
       fputc(b, f);
@@ -289,7 +289,7 @@ bool PcxFormat::onSave(FileOp* fop)
   }
 
   if (ferror(f)) {
-    fop_error(fop, "Error writing file.\n");
+    fop->setError("Error writing file.\n");
     return false;
   }
   else {
diff --git a/src/app/file/png_format.cpp b/src/app/file/png_format.cpp
index 58ca747..971e0cd 100644
--- a/src/app/file/png_format.cpp
+++ b/src/app/file/png_format.cpp
@@ -56,7 +56,7 @@ FileFormat* CreatePngFormat()
 
 static void report_png_error(png_structp png_ptr, png_const_charp error)
 {
-  fop_error((FileOp*)png_get_error_ptr(png_ptr), "libpng: %s\n", error);
+  ((FileOp*)png_get_error_ptr(png_ptr))->setError("libpng: %s\n", error);
 }
 
 bool PngFormat::onLoad(FileOp* fop)
@@ -72,7 +72,7 @@ bool PngFormat::onLoad(FileOp* fop)
   png_bytep row_pointer;
   PixelFormat pixelFormat;
 
-  FileHandle handle(open_file_with_exception(fop->filename, "rb"));
+  FileHandle handle(open_file_with_exception(fop->filename(), "rb"));
   FILE* fp = handle.get();
 
   /* Create and initialize the png_struct with the desired error handler
@@ -84,14 +84,14 @@ bool PngFormat::onLoad(FileOp* fop)
   png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)fop,
                                    report_png_error, report_png_error);
   if (png_ptr == NULL) {
-    fop_error(fop, "png_create_read_struct\n");
+    fop->setError("png_create_read_struct\n");
     return false;
   }
 
   /* Allocate/initialize the memory for image information. */
   info_ptr = png_create_info_struct(png_ptr);
   if (info_ptr == NULL) {
-    fop_error(fop, "png_create_info_struct\n");
+    fop->setError("png_create_info_struct\n");
     png_destroy_read_struct(&png_ptr, NULL, NULL);
     return false;
   }
@@ -100,7 +100,7 @@ bool PngFormat::onLoad(FileOp* fop)
    * the normal method of doing things with libpng).
    */
   if (setjmp(png_jmpbuf(png_ptr))) {
-    fop_error(fop, "Error reading PNG file\n");
+    fop->setError("Error reading PNG file\n");
     /* Free all of the memory associated with the png_ptr and info_ptr */
     png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
     /* If we get here, we had a problem reading the file */
@@ -155,13 +155,13 @@ bool PngFormat::onLoad(FileOp* fop)
   switch (png_get_color_type(png_ptr, info_ptr)) {
 
     case PNG_COLOR_TYPE_RGB_ALPHA:
-      fop->seq.has_alpha = true;
+      fop->sequenceSetHasAlpha(true);
     case PNG_COLOR_TYPE_RGB:
       pixelFormat = IMAGE_RGB;
       break;
 
     case PNG_COLOR_TYPE_GRAY_ALPHA:
-      fop->seq.has_alpha = true;
+      fop->sequenceSetHasAlpha(true);
     case PNG_COLOR_TYPE_GRAY:
       pixelFormat = IMAGE_GRAYSCALE;
       break;
@@ -171,16 +171,16 @@ bool PngFormat::onLoad(FileOp* fop)
       break;
 
     default:
-      fop_error(fop, "Color type not supported\n)");
+      fop->setError("Color type not supported\n)");
       png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
       return false;
   }
 
   int imageWidth = png_get_image_width(png_ptr, info_ptr);
   int imageHeight = png_get_image_height(png_ptr, info_ptr);
-  Image* image = fop_sequence_image(fop, pixelFormat, imageWidth, imageHeight);
+  Image* image = fop->sequenceImage(pixelFormat, imageWidth, imageHeight);
   if (!image) {
-    fop_error(fop, "file_sequence_image %dx%d\n", imageWidth, imageHeight);
+    fop->setError("file_sequence_image %dx%d\n", imageWidth, imageHeight);
     png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
     return false;
   }
@@ -191,13 +191,13 @@ bool PngFormat::onLoad(FileOp* fop)
   // Read the palette
   if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_PALETTE &&
       png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette)) {
-    fop_sequence_set_ncolors(fop, num_palette);
+    fop->sequenceSetNColors(num_palette);
 
     for (int c=0; c<num_palette; ++c) {
-      fop_sequence_set_color(fop, c,
-                             palette[c].red,
-                             palette[c].green,
-                             palette[c].blue);
+      fop->sequenceSetColor(c,
+                            palette[c].red,
+                            palette[c].green,
+                            palette[c].blue);
     }
 
     // Read alpha values for palette entries
@@ -208,10 +208,10 @@ bool PngFormat::onLoad(FileOp* fop)
     png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, nullptr);
 
     for (int i = 0; i < num_trans; ++i) {
-      fop_sequence_set_alpha(fop, i, trans[i]);
+      fop->sequenceSetAlpha(i, trans[i]);
 
       if (trans[i] < 255) {
-        fop->seq.has_alpha = true; // Is a transparent sprite
+        fop->sequenceSetHasAlpha(true); // Is a transparent sprite
         if (trans[i] == 0) {
           if (mask_entry < 0)
             mask_entry = i;
@@ -220,7 +220,7 @@ bool PngFormat::onLoad(FileOp* fop)
     }
 
     if (mask_entry >= 0)
-      fop->document->sprite()->setTransparentColor(mask_entry);
+      fop->document()->sprite()->setTransparentColor(mask_entry);
   }
   else {
     png_get_tRNS(png_ptr, info_ptr, nullptr, nullptr, &png_trans_color);
@@ -264,8 +264,8 @@ bool PngFormat::onLoad(FileOp* fop)
               g == png_trans_color->green &&
               b == png_trans_color->blue) {
             a = 0;
-            if (!fop->seq.has_alpha)
-              fop->seq.has_alpha = true;
+            if (!fop->sequenceGetHasAlpha())
+              fop->sequenceSetHasAlpha(true);
           }
           else
             a = 255;
@@ -298,8 +298,8 @@ bool PngFormat::onLoad(FileOp* fop)
           if (png_trans_color &&
               k == png_trans_color->gray) {
             a = 0;
-            if (!fop->seq.has_alpha)
-              fop->seq.has_alpha = true;
+            if (!fop->sequenceGetHasAlpha())
+              fop->sequenceSetHasAlpha(true);
           }
           else
             a = 255;
@@ -317,11 +317,11 @@ bool PngFormat::onLoad(FileOp* fop)
           *(dst_address++) = *(src_address++);
       }
 
-      fop_progress(fop,
-                   (double)((double)pass + (double)(y+1) / (double)(height))
-                   / (double)number_passes);
+      fop->setProgress(
+        (double)((double)pass + (double)(y+1) / (double)(height))
+        / (double)number_passes);
 
-      if (fop_is_stop(fop))
+      if (fop->isStop())
         break;
     }
   }
@@ -335,7 +335,7 @@ bool PngFormat::onLoad(FileOp* fop)
 #ifdef ENABLE_SAVE
 bool PngFormat::onSave(FileOp* fop)
 {
-  Image* image = fop->seq.image.get();
+  const Image* image = fop->sequenceImage();
   png_uint_32 width, height, y;
   png_structp png_ptr;
   png_infop info_ptr;
@@ -345,7 +345,7 @@ bool PngFormat::onSave(FileOp* fop)
   int pass, number_passes;
 
   /* open the file */
-  FileHandle handle(open_file_with_exception(fop->filename, "wb"));
+  FileHandle handle(open_file_with_exception(fop->filename(), "wb"));
   FILE* fp = handle.get();
 
   /* Create and initialize the png_struct with the desired error handler
@@ -392,12 +392,12 @@ bool PngFormat::onSave(FileOp* fop)
 
   switch (image->pixelFormat()) {
     case IMAGE_RGB:
-      color_type = fop->document->sprite()->needAlpha() ?
+      color_type = fop->document()->sprite()->needAlpha() ?
         PNG_COLOR_TYPE_RGB_ALPHA:
         PNG_COLOR_TYPE_RGB;
       break;
     case IMAGE_GRAYSCALE:
-      color_type = fop->document->sprite()->needAlpha() ?
+      color_type = fop->document()->sprite()->needAlpha() ?
         PNG_COLOR_TYPE_GRAY_ALPHA:
         PNG_COLOR_TYPE_GRAY;
       break;
@@ -411,7 +411,7 @@ bool PngFormat::onSave(FileOp* fop)
 
   if (image->pixelFormat() == IMAGE_INDEXED) {
     int c, r, g, b;
-    int pal_size = fop_sequence_get_ncolors(fop);
+    int pal_size = fop->sequenceGetNColors();
     pal_size = MID(1, pal_size, PNG_MAX_PALETTE_LENGTH);
 
 #if PNG_MAX_PALETTE_LENGTH != 256
@@ -421,7 +421,7 @@ bool PngFormat::onSave(FileOp* fop)
     // Save the color palette.
     palette = (png_colorp)png_malloc(png_ptr, pal_size * sizeof(png_color));
     for (c = 0; c < pal_size; c++) {
-      fop_sequence_get_color(fop, c, &r, &g, &b);
+      fop->sequenceGetColor(c, &r, &g, &b);
       palette[c].red   = r;
       palette[c].green = g;
       palette[c].blue  = b;
@@ -432,9 +432,9 @@ bool PngFormat::onSave(FileOp* fop)
     // If the sprite does not have a (visible) background layer, we
     // put alpha=0 to the transparent color.
     int mask_entry = -1;
-    if (fop->document->sprite()->backgroundLayer() == NULL ||
-        !fop->document->sprite()->backgroundLayer()->isVisible()) {
-      mask_entry = fop->document->sprite()->transparentColor();
+    if (fop->document()->sprite()->backgroundLayer() == NULL ||
+        !fop->document()->sprite()->backgroundLayer()->isVisible()) {
+      mask_entry = fop->document()->sprite()->transparentColor();
     }
 
     int num_trans = pal_size;
@@ -442,7 +442,7 @@ bool PngFormat::onSave(FileOp* fop)
 
     for (c=0; c<num_trans; ++c) {
       int alpha = 255;
-      fop_sequence_get_alpha(fop, c, &alpha);
+      fop->sequenceGetAlpha(c, &alpha);
       trans[c] = (c == mask_entry ? 0: alpha);
     }
 
@@ -530,9 +530,9 @@ bool PngFormat::onSave(FileOp* fop)
       /* write the line */
       png_write_rows(png_ptr, &row_pointer, 1);
 
-      fop_progress(fop,
-                   (double)((double)pass + (double)(y+1) / (double)(height))
-                   / (double)number_passes);
+      fop->setProgress(
+        (double)((double)pass + (double)(y+1) / (double)(height))
+        / (double)number_passes);
     }
   }
 
diff --git a/src/app/file/tga_format.cpp b/src/app/file/tga_format.cpp
index cfac2fa..4db1dd9 100644
--- a/src/app/file/tga_format.cpp
+++ b/src/app/file/tga_format.cpp
@@ -197,7 +197,7 @@ bool TgaFormat::onLoad(FileOp* fop)
   unsigned int c, i, x, y, yc;
   int compressed;
 
-  FileHandle handle(open_file_with_exception(fop->filename, "rb"));
+  FileHandle handle(open_file_with_exception(fop->filename(), "rb"));
   FILE* f = handle.get();
 
   id_length = fgetc(f);
@@ -264,10 +264,10 @@ bool TgaFormat::onLoad(FileOp* fop)
       }
 
       for (i=0; i<palette_colors; i++) {
-        fop_sequence_set_color(fop, i,
-                               image_palette[i][2],
-                               image_palette[i][1],
-                               image_palette[i][0]);
+        fop->sequenceSetColor(i,
+                              image_palette[i][2],
+                              image_palette[i][1],
+                              image_palette[i][0]);
       }
 
       pixelFormat = IMAGE_INDEXED;
@@ -291,7 +291,7 @@ bool TgaFormat::onLoad(FileOp* fop)
       }
 
       for (i=0; i<256; i++)
-        fop_sequence_set_color(fop, i, i, i, i);
+        fop->sequenceSetColor(i, i, i, i);
 
       pixelFormat = IMAGE_GRAYSCALE;
       break;
@@ -301,7 +301,7 @@ bool TgaFormat::onLoad(FileOp* fop)
       return false;
   }
 
-  Image* image = fop_sequence_image(fop, pixelFormat, image_width, image_height);
+  Image* image = fop->sequenceImage(pixelFormat, image_width, image_height);
   if (!image)
     return false;
 
@@ -362,14 +362,14 @@ bool TgaFormat::onLoad(FileOp* fop)
     }
 
     if (image_height > 1) {
-      fop_progress(fop, (float)(image_height-y) / (float)(image_height));
-      if (fop_is_stop(fop))
+      fop->setProgress((float)(image_height-y) / (float)(image_height));
+      if (fop->isStop())
         break;
     }
   }
 
   if (ferror(f)) {
-    fop_error(fop, "Error reading file.\n");
+    fop->setError("Error reading file.\n");
     return false;
   }
   else {
@@ -382,13 +382,13 @@ bool TgaFormat::onLoad(FileOp* fop)
 // should be an array of at least 256 RGB structures).
 bool TgaFormat::onSave(FileOp* fop)
 {
-  Image* image = fop->seq.image.get();
+  const Image* image = fop->sequenceImage();
   unsigned char image_palette[256][3];
   int x, y, c, r, g, b;
   int depth = (image->pixelFormat() == IMAGE_RGB) ? 32 : 8;
   bool need_pal = (image->pixelFormat() == IMAGE_INDEXED)? true: false;
 
-  FileHandle handle(open_file_with_exception(fop->filename, "wb"));
+  FileHandle handle(open_file_with_exception(fop->filename(), "wb"));
   FILE* f = handle.get();
 
   fputc(0, f);                          /* id length (no id saved) */
@@ -411,7 +411,7 @@ bool TgaFormat::onSave(FileOp* fop)
 
   if (need_pal) {
     for (y=0; y<256; y++) {
-      fop_sequence_get_color(fop, y, &r, &g, &b);
+      fop->sequenceGetColor(y, &r, &g, &b);
       image_palette[y][2] = r;
       image_palette[y][1] = g;
       image_palette[y][0] = b;
@@ -431,7 +431,7 @@ bool TgaFormat::onSave(FileOp* fop)
           fputc(rgba_geta(c), f);
         }
 
-        fop_progress(fop, (float)(image->height()-y) / (float)(image->height()));
+        fop->setProgress((float)(image->height()-y) / (float)(image->height()));
       }
       break;
 
@@ -440,7 +440,7 @@ bool TgaFormat::onSave(FileOp* fop)
         for (x=0; x<image->width(); x++)
           fputc(graya_getv(get_pixel(image, x, y)), f);
 
-        fop_progress(fop, (float)(image->height()-y) / (float)(image->height()));
+        fop->setProgress((float)(image->height()-y) / (float)(image->height()));
       }
       break;
 
@@ -449,13 +449,13 @@ bool TgaFormat::onSave(FileOp* fop)
         for (x=0; x<image->width(); x++)
           fputc(get_pixel(image, x, y), f);
 
-        fop_progress(fop, (float)(image->height()-y) / (float)(image->height()));
+        fop->setProgress((float)(image->height()-y) / (float)(image->height()));
       }
       break;
   }
 
   if (ferror(f)) {
-    fop_error(fop, "Error writing file.\n");
+    fop->setError("Error writing file.\n");
     return false;
   }
   else {
diff --git a/src/app/file/webp_format.cpp b/src/app/file/webp_format.cpp
index 3df1f16..2c13cf8 100644
--- a/src/app/file/webp_format.cpp
+++ b/src/app/file/webp_format.cpp
@@ -29,8 +29,7 @@
 #include <algorithm>
 #include <map>
 
-
-//include webp librarys
+// Include webp libraries
 #include <webp/decode.h>
 #include <webp/encode.h>
 
@@ -65,27 +64,28 @@ FileFormat* CreateWebPFormat()
   return new WebPFormat;
 }
 
-const char* getDecoderErrorMessage(VP8StatusCode statusCode) {
+const char* getDecoderErrorMessage(VP8StatusCode statusCode)
+{
   switch (statusCode) {
-  case VP8_STATUS_OK: return ""; break;
-  case VP8_STATUS_OUT_OF_MEMORY: return "out of memory"; break;
-  case VP8_STATUS_INVALID_PARAM: return "invalid parameters"; break;
-  case VP8_STATUS_BITSTREAM_ERROR: return "bitstream error"; break;
-  case VP8_STATUS_UNSUPPORTED_FEATURE: return "unsupported feature"; break;
-  case VP8_STATUS_SUSPENDED: return "suspended"; break;
-  case VP8_STATUS_USER_ABORT: return "user aborted"; break;
-  case VP8_STATUS_NOT_ENOUGH_DATA: return "not enough data"; break;
-  default: return "unknown error"; break;
+    case VP8_STATUS_OK: return ""; break;
+    case VP8_STATUS_OUT_OF_MEMORY: return "out of memory"; break;
+    case VP8_STATUS_INVALID_PARAM: return "invalid parameters"; break;
+    case VP8_STATUS_BITSTREAM_ERROR: return "bitstream error"; break;
+    case VP8_STATUS_UNSUPPORTED_FEATURE: return "unsupported feature"; break;
+    case VP8_STATUS_SUSPENDED: return "suspended"; break;
+    case VP8_STATUS_USER_ABORT: return "user aborted"; break;
+    case VP8_STATUS_NOT_ENOUGH_DATA: return "not enough data"; break;
+    default: return "unknown error"; break;
   }
 }
 
 bool WebPFormat::onLoad(FileOp* fop)
 {
-  FileHandle handle(open_file_with_exception(fop->filename, "rb"));
+  FileHandle handle(open_file_with_exception(fop->filename(), "rb"));
   FILE* fp = handle.get();
 
   if (fseek(fp, 0, SEEK_END) != 0) {
-    fop_error(fop, "Error while getting WebP file size for %s\n", fop->filename.c_str());
+    fop->setError("Error while getting WebP file size for %s\n", fop->filename().c_str());
     return false;
   }
 
@@ -93,7 +93,7 @@ bool WebPFormat::onLoad(FileOp* fop)
   rewind(fp);
 
   if (len < 4) {
-    fop_error(fop, "%s is corrupt or not a WebP file\n", fop->filename.c_str());
+    fop->setError("%s is corrupt or not a WebP file\n", fop->filename().c_str());
     return false;
   }
 
@@ -101,24 +101,24 @@ bool WebPFormat::onLoad(FileOp* fop)
   uint8_t* data = &buf.front();
 
   if (!fread(data, sizeof(uint8_t), len, fp)) {
-    fop_error(fop, "Error while writing to %s to memory\n", fop->filename.c_str());
+    fop->setError("Error while writing to %s to memory\n", fop->filename().c_str());
     return false;
   }
 
   WebPDecoderConfig config;
   if (!WebPInitDecoderConfig(&config)) {
-    fop_error(fop, "LibWebP version mismatch %s\n", fop->filename.c_str());
+    fop->setError("LibWebP version mismatch %s\n", fop->filename().c_str());
     return false;
   }
 
   if (WebPGetFeatures(data, len, &config.input) != VP8_STATUS_OK) {
-    fop_error(fop, "Bad bitstream in %s\n", fop->filename.c_str());
+    fop->setError("Bad bitstream in %s\n", fop->filename().c_str());
     return false;
   }
 
-  fop->seq.has_alpha = (config.input.has_alpha != 0);
+  fop->sequenceSetHasAlpha(config.input.has_alpha != 0);
 
-  Image* image = fop_sequence_image(fop, IMAGE_RGB, config.input.width, config.input.height);
+  Image* image = fop->sequenceImage(IMAGE_RGB, config.input.width, config.input.height);
 
   config.output.colorspace = MODE_RGBA;
   config.output.u.RGBA.rgba = (uint8_t*)image->getPixelAddress(0, 0);
@@ -128,7 +128,7 @@ bool WebPFormat::onLoad(FileOp* fop)
 
   WebPIDecoder* idec = WebPIDecode(NULL, 0, &config);
   if (idec == NULL) {
-    fop_error(fop, "Error creating WebP decoder for %s\n", fop->filename.c_str());
+    fop->setError("Error creating WebP decoder for %s\n", fop->filename().c_str());
     return false;
   }
 
@@ -141,19 +141,20 @@ bool WebPFormat::onLoad(FileOp* fop)
       bytes_remaining -= bytes_read;
       data += bytes_read;
       if (bytes_remaining < bytes_read) bytes_read = bytes_remaining;
-      fop_progress(fop, 1.0f - ((float)std::max(bytes_remaining, 0l)/(float)len));
+      fop->setProgress(1.0f - ((float)std::max(bytes_remaining, 0l)/(float)len));
     } else {
-      fop_error(fop, "Error during decoding %s : %s\n", fop->filename.c_str(), getDecoderErrorMessage(status));
+      fop->setError("Error during decoding %s : %s\n",
+                    fop->filename().c_str(), getDecoderErrorMessage(status));
       WebPIDelete(idec);
       WebPFreeDecBuffer(&config.output);
       return false;
     }
-    if (fop_is_stop(fop))
+    if (fop->isStop())
       break;
   }
 
   base::SharedPtr<WebPOptions> webPOptions = base::SharedPtr<WebPOptions>(new WebPOptions());
-  fop->seq.format_options = webPOptions;
+  fop->sequenceSetFormatOptions(webPOptions);
   webPOptions->setLossless(std::min(config.input.format - 1, 1));
 
   WebPIDelete(idec);
@@ -162,7 +163,8 @@ bool WebPFormat::onLoad(FileOp* fop)
 }
 
 #ifdef ENABLE_SAVE
-struct writerData {
+
+struct WriterData {
   FILE* fp;
   FileOp* fop;
 };
@@ -206,57 +208,62 @@ int WebPConfigLosslessPreset(WebPConfig* config, int level) {
 
 static int ProgressReport(int percent, const WebPPicture* const pic)
 {
-  fop_progress(((writerData*)pic->custom_ptr)->fop, (double)percent/(double)100);
-  if (fop_is_stop(((writerData*)pic->custom_ptr)->fop)) return false;
-  return true;
+  FileOp* fop = ((WriterData*)pic->custom_ptr)->fop;
+  fop->setProgress((double)percent/(double)100);
+  if (fop->isStop())
+    return false;
+  else
+    return true;
 }
 
 static int FileWriter(const uint8_t* data, size_t data_size, const WebPPicture* const pic)
 {
-  return data_size ? (fwrite(data, data_size, 1, ((writerData*)pic->custom_ptr)->fp) == 1) : 1;
+  return (data_size ? (fwrite(data, data_size, 1, ((WriterData*)pic->custom_ptr)->fp) == 1) : 1);
 }
 
 bool WebPFormat::onSave(FileOp* fop)
 {
-  FileHandle handle(open_file_with_exception(fop->filename, "wb"));
+  FileHandle handle(open_file_with_exception(fop->filename(), "wb"));
   FILE* fp = handle.get();
 
-  struct writerData wd = {fp, fop};
+  WriterData wd = { fp, fop };
 
-  Image* image = fop->seq.image.get();
-  if (image->width() > WEBP_MAX_DIMENSION || image->height() > WEBP_MAX_DIMENSION) {
-   fop_error(
-     fop, "Error: WebP can only have a maximum width and height of %i but your %s has a size of %i x %i\n",
-     WEBP_MAX_DIMENSION, fop->filename.c_str(), image->width(), image->height()
+  const Image* image = fop->sequenceImage();
+  if (image->width() > WEBP_MAX_DIMENSION ||
+      image->height() > WEBP_MAX_DIMENSION) {
+   fop->setError("Error: WebP can only have a maximum width and height of %i but your %s has a size of %i x %i\n",
+                 WEBP_MAX_DIMENSION, fop->filename().c_str(), image->width(), image->height()
    );
    return false;
   }
 
-  base::SharedPtr<WebPOptions> webp_options = fop->seq.format_options;
+  base::SharedPtr<WebPOptions> webp_options =
+    fop->sequenceGetFormatOptions();
 
   WebPConfig config;
 
   if (webp_options->lossless()) {
     if (!(WebPConfigInit(&config) && WebPConfigLosslessPreset(&config, webp_options->getMethod()))) {
-     fop_error(fop, "Error for WebP Config Version for file %s\n", fop->filename.c_str());
-     return false;
+      fop->setError("Error for WebP Config Version for file %s\n", fop->filename().c_str());
+      return false;
     }
     config.image_hint = webp_options->getImageHint();
-  } else {
+  }
+  else {
     if (!WebPConfigPreset(&config, webp_options->getImagePreset(), static_cast<float>(webp_options->getQuality()))) {
-     fop_error(fop, "Error for WebP Config Version for file %s\n", fop->filename.c_str());
-     return false;
+      fop->setError("Error for WebP Config Version for file %s\n", fop->filename().c_str());
+      return false;
     }
   }
 
   if (!WebPValidateConfig(&config)) {
-   fop_error(fop, "Error in WebP Encoder Config for file %s\n", fop->filename.c_str());
-   return false;
+    fop->setError("Error in WebP Encoder Config for file %s\n", fop->filename().c_str());
+    return false;
   }
 
   WebPPicture pic;
   if (!WebPPictureInit(&pic)) {
-    fop_error(fop, "Error for WebP Picture Version mismatch for file %s\n", fop->filename.c_str());
+    fop->setError("Error for WebP Picture Version mismatch for file %s\n", fop->filename().c_str());
     return false;
   }
 
@@ -267,12 +274,12 @@ bool WebPFormat::onSave(FileOp* fop)
   }
 
   if (!WebPPictureAlloc(&pic)) {
-    fop_error(fop, "Error for  WebP Picture memory allocations for file %s\n", fop->filename.c_str());
+    fop->setError("Error for  WebP Picture memory allocations for file %s\n", fop->filename().c_str());
     return false;
   }
 
   if (!WebPPictureImportRGBA(&pic, (uint8_t*)image->getPixelAddress(0, 0), image->width() * sizeof(uint32_t))) {
-    fop_error(fop, "Error for LibWebP Import RGBA Buffer into Picture for %s\n", fop->filename.c_str());
+    fop->setError("Error for LibWebP Import RGBA Buffer into Picture for %s\n", fop->filename().c_str());
     WebPPictureFree(&pic);
     return false;
   }
@@ -282,7 +289,8 @@ bool WebPFormat::onSave(FileOp* fop)
   pic.progress_hook = ProgressReport;
 
   if (!WebPEncode(&config, &pic)) {
-    fop_error(fop, "Error for LibWebP while Encoding %s: %s\n", fop->filename.c_str(), getEncoderErrorMessage(pic.error_code));
+    fop->setError("Error for LibWebP while Encoding %s: %s\n",
+                  fop->filename().c_str(), getEncoderErrorMessage(pic.error_code));
     WebPPictureFree(&pic);
     return false;
   }
@@ -290,20 +298,22 @@ bool WebPFormat::onSave(FileOp* fop)
   WebPPictureFree(&pic);
   return true;
 }
-#endif
+
+#endif  // ENABLE_SAVE
 
 // Shows the WebP configuration dialog.
 base::SharedPtr<FormatOptions> WebPFormat::onGetFormatOptions(FileOp* fop)
 {
   base::SharedPtr<WebPOptions> webp_options;
-  if (fop->document->getFormatOptions())
-    webp_options = base::SharedPtr<WebPOptions>(fop->document->getFormatOptions());
+  if (fop->document()->getFormatOptions())
+    webp_options = base::SharedPtr<WebPOptions>(fop->document()->getFormatOptions());
 
   if (!webp_options)
     webp_options.reset(new WebPOptions);
 
   // Non-interactive mode
-  if (!fop->context || !fop->context->isUIAvailable())
+  if (!fop->context() ||
+      !fop->context()->isUIAvailable())
     return webp_options;
 
   try {
diff --git a/src/app/thumbnail_generator.cpp b/src/app/thumbnail_generator.cpp
index 39869f3..46a34a9 100644
--- a/src/app/thumbnail_generator.cpp
+++ b/src/app/thumbnail_generator.cpp
@@ -42,29 +42,29 @@ public:
   }
 
   ~Worker() {
-    fop_stop(m_fop);
+    m_fop->stop();
     m_thread.join();
-
-    fop_free(m_fop);
   }
 
   IFileItem* getFileItem() { return m_fileitem; }
-  bool isDone() const { return fop_is_done(m_fop); }
-  double getProgress() const { return fop_get_progress(m_fop); }
+  bool isDone() const { return m_fop->isDone(); }
+  double getProgress() const { return m_fop->progress(); }
 
 private:
   void loadBgThread() {
     try {
-      fop_operate(m_fop, NULL);
+      m_fop->operate(nullptr);
 
       // Post load
-      fop_post_load(m_fop);
+      m_fop->postLoad();
 
       // Convert the loaded document into the she::Surface.
-      const Sprite* sprite = (m_fop->document && m_fop->document->sprite()) ?
-        m_fop->document->sprite(): NULL;
+      const Sprite* sprite =
+        (m_fop->document() &&
+         m_fop->document()->sprite() ?
+         m_fop->document()->sprite(): nullptr);
 
-      if (!fop_is_stop(m_fop) && sprite) {
+      if (!m_fop->isStop() && sprite) {
         // The palette to convert the Image
         m_palette.reset(new Palette(*sprite->palette(frame_t(0))));
 
@@ -96,7 +96,7 @@ private:
       }
 
       // Close file
-      delete m_fop->document;
+      delete m_fop->releaseDocument();
 
       // Set the thumbnail of the file-item.
       if (m_thumbnail) {
@@ -111,12 +111,12 @@ private:
       }
     }
     catch (const std::exception& e) {
-      fop_error(m_fop, "Error loading file:\n%s", e.what());
+      m_fop->setError("Error loading file:\n%s", e.what());
     }
-    fop_done(m_fop);
+    m_fop->done();
   }
 
-  FileOp* m_fop;
+  base::UniquePtr<FileOp> m_fop;
   IFileItem* m_fileitem;
   base::UniquePtr<Image> m_thumbnail;
   base::UniquePtr<Palette> m_palette;
@@ -185,27 +185,26 @@ void ThumbnailGenerator::addWorkerToGenerateThumbnail(IFileItem* fileitem)
       getWorkerStatus(fileitem, progress) != WithoutWorker)
     return;
 
-  FileOp* fop = fop_to_load_document(NULL,
-    fileitem->getFileName().c_str(),
-    FILE_LOAD_SEQUENCE_NONE |
-    FILE_LOAD_ONE_FRAME);
-
+  base::UniquePtr<FileOp> fop(
+    FileOp::createLoadDocumentOperation(
+      nullptr,
+      fileitem->getFileName().c_str(),
+      FILE_LOAD_SEQUENCE_NONE |
+      FILE_LOAD_ONE_FRAME));
   if (!fop)
     return;
 
-  if (fop->has_error()) {
-    fop_free(fop);
+  if (fop->hasError())
+    return;
+
+  Worker* worker = new Worker(fop.release(), fileitem);
+  try {
+    base::scoped_lock hold(m_workersAccess);
+    m_workers.push_back(worker);
   }
-  else {
-    Worker* worker = new Worker(fop, fileitem);
-    try {
-      base::scoped_lock hold(m_workersAccess);
-      m_workers.push_back(worker);
-    }
-    catch (...) {
-      delete worker;
-      throw;
-    }
+  catch (...) {
+    delete worker;
+    throw;
   }
 }
 
@@ -224,10 +223,8 @@ void ThumbnailGenerator::stopAllWorkersBackground()
     m_workers.clear();
   }
 
-  for (WorkerList::iterator
-         it=workersCopy.begin(), end=workersCopy.end(); it!=end; ++it) {
+  for (auto it=workersCopy.begin(), end=workersCopy.end(); it!=end; ++it)
     delete *it;
-  }
 }
 
 } // namespace app

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/aseprite.git



More information about the Pkg-games-commits mailing list