diff --git a/src/app/commands/cmd_open_file.cpp b/src/app/commands/cmd_open_file.cpp index b772ce325..145b2e2f9 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 fop(fop_to_load_document(context, m_filename.c_str(), FILE_LOAD_SEQUENCE_ASK)); + base::UniquePtr 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 1d9d3747a..90c62eca5 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 fop(fop_to_save_document(context, - document, document->filename().c_str(), fn_format.c_str())); + base::UniquePtr 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)->impossibleToBackToSavedState(); } // If the job was cancelled, mark the document as modified. - else if (fop_is_stop(fop)) { + else if (fop->isStop()) { const_cast(document)->impossibleToBackToSavedState(); } else if (context->isUIAvailable()) { diff --git a/src/app/file/ase_format.cpp b/src/app/file/ase_format.cpp index cf7fbd10c..1b77c3754 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); frametotalFrames(); ++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; csetProgress((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(layer)->getLayerBegin(); - LayerIterator end = static_cast(layer)->getLayerEnd(); + auto it = static_cast(layer)->getLayerBegin(), + end = static_cast(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(layer), sprite); + ase_file_write_cel_chunk(f, frame_header, cel, static_cast(layer), sprite); } } if (layer->isFolder()) { - LayerIterator it = static_cast(layer)->getLayerBegin(); - LayerIterator end = static_cast(layer)->getLayerEnd(); + auto it = static_cast(layer)->getLayerBegin(), + end = static_cast(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(layer)->blendMode(): 0, f); - fputc(layer->isImage() ? (int)static_cast(layer)->opacity(): 0, f); + fputw(layer->isImage() ? (int)static_cast(layer)->blendMode(): 0, f); + fputc(layer->isImage() ? (int)static_cast(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; xwidth(); x++) put_pixel_fast(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 -static void write_raw_image(FILE* f, Image* image) +static void write_raw_image(FILE* f, const Image* image) { PixelIO 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 -static void write_compressed_image(FILE* f, Image* image) +static void write_compressed_image(FILE* f, const Image* image) { PixelIO 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 3f6da0239..11ae684b0 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 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; jheight()-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 a2559f139..1ca306744 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 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(document)); - int ret; - FileOp* fop = fop_to_save_document(context, - static_cast(document), - document->filename().c_str(), ""); + UniquePtr fop( + FileOp::createSaveDocumentOperation( + context, + static_cast(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 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" "<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)); - if (!fop) - return NULL; + base::UniquePtr fop( + new FileOp(FileOpSave, const_cast(context))); // Document to save - fop->document = const_cast(document); + fop->m_document = const_cast(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; csize(); ++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, "<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 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 format_options = fop->format->getFormatOptions(fop); + if (fop->m_format->support(FILE_SUPPORT_GET_FORMAT_OPTIONS)) { + base::SharedPtr 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::iterator it = fop->seq.filename_list.begin(); - std::vector::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); + ASSERT(m_document == NULL); + m_document = new Document(spr); } -void fop_free(FileOp *fop) +void FileOp::postLoad() { - delete fop; -} - -void fop_post_load(FileOp* fop) -{ - 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(); } -void fop_sequence_set_format_options(FileOp* fop, const base::SharedPtr& format_options) +base::SharedPtr FileOp::sequenceGetFormatOptions() const { - ASSERT(!fop->seq.format_options); - fop->seq.format_options = format_options; + return m_seq.format_options; } -void fop_sequence_set_ncolors(FileOp* fop, int ncolors) +void FileOp::sequenceSetFormatOptions(const base::SharedPtr& format_options) { - fop->seq.palette->resize(ncolors); + ASSERT(!m_seq.format_options); + m_seq.format_options = format_options; } -int fop_sequence_get_ncolors(FileOp* fop) +void FileOp::sequenceSetNColors(int ncolors) { - return fop->seq.palette->size(); + m_seq.palette->resize(ncolors); } -void fop_sequence_set_color(FileOp *fop, int index, int r, int g, int b) +int FileOp::sequenceGetNColors() const { - fop->seq.palette->setEntry(index, rgba(r, g, b, 255)); + return m_seq.palette->size(); } -void fop_sequence_get_color(FileOp *fop, int index, int *r, int *g, int *b) +void FileOp::sequenceSetColor(int index, int r, int g, int b) +{ + m_seq.palette->setEntry(index, rgba(r, g, b, 255)); +} + +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 8e5babfeb..432fcd843 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 sequenceGetFormatOptions() const; + void sequenceSetFormatOptions(const base::SharedPtr& 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 format_options; - } seq; + } m_seq; - ~FileOp(); - - 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& 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 e6f179079..ed5d774a8 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 919eb7788..3631b024b 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 f47facd2a..6d95951ae 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 = fop->seq.format_options; + const base::SharedPtr 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 GifFormat::onGetFormatOptions(FileOp* fop) { base::SharedPtr gif_options; - if (fop->document->getFormatOptions()) - gif_options = base::SharedPtr(fop->document->getFormatOptions()); + if (fop->document()->getFormatOptions()) + gif_options = base::SharedPtr(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 db66ff09f..320233a81 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 6f968f100..cb6622c11 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 jpeg_options = fop->seq.format_options; + const base::SharedPtr 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 JpegFormat::onGetFormatOptions(FileOp* fop) { base::SharedPtr jpeg_options; - if (fop->document->getFormatOptions()) - jpeg_options = base::SharedPtr(fop->document->getFormatOptions()); + if (fop->document()->getFormatOptions()) + jpeg_options = base::SharedPtr(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 c092acc87..6ebe2c0b0 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); + base::UniquePtr fop( + FileOp::createLoadDocumentOperation( + nullptr, filename, + FILE_LOAD_SEQUENCE_NONE | + FILE_LOAD_ONE_FRAME)); - if (fop->document && - fop->document->sprite() && - fop->document->sprite()->palette(frame_t(0))) { + 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 4a9eb280f..0a5daa040 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 58ca747d8..971e0cd18 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; csequenceSetColor(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; csequenceGetAlpha(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 cfac2fa33..4db1dd97f 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; isequenceSetColor(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; xwidth(); 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; xwidth(); 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 3df1f1687..2c13cf855 100644 --- a/src/app/file/webp_format.cpp +++ b/src/app/file/webp_format.cpp @@ -29,8 +29,7 @@ #include #include - -//include webp librarys +// Include webp libraries #include #include @@ -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 = base::SharedPtr(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 webp_options = fop->seq.format_options; + base::SharedPtr 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(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 WebPFormat::onGetFormatOptions(FileOp* fop) { base::SharedPtr webp_options; - if (fop->document->getFormatOptions()) - webp_options = base::SharedPtr(fop->document->getFormatOptions()); + if (fop->document()->getFormatOptions()) + webp_options = base::SharedPtr(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 39869f3b9..46a34a99c 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 m_fop; IFileItem* m_fileitem; base::UniquePtr m_thumbnail; base::UniquePtr 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 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