Convert FileOp into a class

This commit is contained in:
David Capello 2015-09-29 11:27:00 -03:00
parent ee0aae0e3c
commit c30112ea10
17 changed files with 697 additions and 683 deletions

View File

@ -60,7 +60,7 @@ public:
startJob();
if (isCanceled())
fop_stop(m_fop);
m_fop->stop();
waitJob();
}
@ -69,18 +69,16 @@ private:
// Thread to do the hard work: load the file from the disk.
virtual void onJob() override {
try {
fop_operate(m_fop, this);
m_fop->operate(this);
}
catch (const std::exception& e) {
fop_error(m_fop, "Error loading file:\n%s", e.what());
m_fop->setError("Error loading file:\n%s", e.what());
}
if (fop_is_stop(m_fop) && m_fop->document) {
delete m_fop->document;
m_fop->document = NULL;
}
if (m_fop->isStop() && m_fop->document())
delete m_fop->releaseDocument();
fop_done(m_fop);
m_fop->done();
}
virtual void ackFileOpProgress(double progress) override {
@ -121,12 +119,14 @@ void OpenFileCommand::onExecute(Context* context)
}
if (!m_filename.empty()) {
base::UniquePtr<FileOp> fop(fop_to_load_document(context, m_filename.c_str(), FILE_LOAD_SEQUENCE_ASK));
base::UniquePtr<FileOp> fop(
FileOp::createLoadDocumentOperation(
context, m_filename.c_str(), FILE_LOAD_SEQUENCE_ASK));
bool unrecent = false;
if (fop) {
if (fop->has_error()) {
console.printf(fop->error.c_str());
if (fop->hasError()) {
console.printf(fop->error().c_str());
unrecent = true;
}
else {
@ -134,20 +134,20 @@ void OpenFileCommand::onExecute(Context* context)
task.showProgressWindow();
// Post-load processing, it is called from the GUI because may require user intervention.
fop_post_load(fop);
fop->postLoad();
// Show any error
if (fop->has_error())
console.printf(fop->error.c_str());
if (fop->hasError())
console.printf(fop->error().c_str());
Document* document = fop->document;
Document* document = fop->document();
if (document) {
if (context->isUIAvailable())
App::instance()->getRecentFiles()->addRecentFile(fop->filename.c_str());
App::instance()->getRecentFiles()->addRecentFile(fop->filename().c_str());
document->setContext(context);
}
else if (!fop_is_stop(fop))
else if (!fop->isStop())
unrecent = true;
}

View File

@ -68,7 +68,7 @@ public:
startJob();
if (isCanceled()) {
fop_stop(m_fop);
m_fop->stop();
}
waitJob();
@ -79,12 +79,12 @@ private:
// Thread to do the hard work: save the file to the disk.
virtual void onJob() override {
try {
fop_operate(m_fop, this);
m_fop->operate(this);
}
catch (const std::exception& e) {
fop_error(m_fop, "Error saving file:\n%s", e.what());
m_fop->setError("Error saving file:\n%s", e.what());
}
fop_done(m_fop);
m_fop->done();
}
virtual void ackFileOpProgress(double progress) override {
@ -98,24 +98,26 @@ static void save_document_in_background(const Context* context,
const Document* document, bool mark_as_saved,
const std::string& fn_format)
{
base::UniquePtr<FileOp> fop(fop_to_save_document(context,
document, document->filename().c_str(), fn_format.c_str()));
base::UniquePtr<FileOp> fop(
FileOp::createSaveDocumentOperation(
context, document,
document->filename().c_str(), fn_format.c_str()));
if (!fop)
return;
SaveFileJob job(fop);
job.showProgressWindow();
if (fop->has_error()) {
if (fop->hasError()) {
Console console;
console.printf(fop->error.c_str());
console.printf(fop->error().c_str());
// We don't know if the file was saved correctly or not. So mark
// it as it should be saved again.
const_cast<Document*>(document)->impossibleToBackToSavedState();
}
// If the job was cancelled, mark the document as modified.
else if (fop_is_stop(fop)) {
else if (fop->isStop()) {
const_cast<Document*>(document)->impossibleToBackToSavedState();
}
else if (context->isUIAvailable()) {

View File

@ -90,8 +90,8 @@ static void ase_file_read_frame_header(FILE* f, ASE_FrameHeader* frame_header);
static void ase_file_prepare_frame_header(FILE* f, ASE_FrameHeader* frame_header);
static void ase_file_write_frame_header(FILE* f, ASE_FrameHeader* frame_header);
static void ase_file_write_layers(FILE* f, ASE_FrameHeader* frame_header, Layer* layer);
static void ase_file_write_cels(FILE* f, ASE_FrameHeader* frame_header, Sprite* sprite, Layer* layer, frame_t frame);
static void ase_file_write_layers(FILE* f, ASE_FrameHeader* frame_header, const Layer* layer);
static void ase_file_write_cels(FILE* f, ASE_FrameHeader* frame_header, const Sprite* sprite, const Layer* layer, frame_t frame);
static void ase_file_read_padding(FILE* f, int bytes);
static void ase_file_write_padding(FILE* f, int bytes);
@ -104,18 +104,18 @@ static void ase_file_write_close_chunk(FILE* f, ASE_Chunk* chunk);
static Palette* ase_file_read_color_chunk(FILE* f, Palette* prevPal, frame_t frame);
static Palette* ase_file_read_color2_chunk(FILE* f, Palette* prevPal, frame_t frame);
static Palette* ase_file_read_palette_chunk(FILE* f, Palette* prevPal, frame_t frame);
static void ase_file_write_color2_chunk(FILE* f, ASE_FrameHeader* frame_header, Palette* pal);
static void ase_file_write_palette_chunk(FILE* f, ASE_FrameHeader* frame_header, Palette* pal, int from, int to);
static void ase_file_write_color2_chunk(FILE* f, ASE_FrameHeader* frame_header, const Palette* pal);
static void ase_file_write_palette_chunk(FILE* f, ASE_FrameHeader* frame_header, const Palette* pal, int from, int to);
static Layer* ase_file_read_layer_chunk(FILE* f, ASE_Header* header, Sprite* sprite, Layer** previous_layer, int* current_level);
static void ase_file_write_layer_chunk(FILE* f, ASE_FrameHeader* frame_header, Layer* layer);
static void ase_file_write_layer_chunk(FILE* f, ASE_FrameHeader* frame_header, const Layer* layer);
static Cel* ase_file_read_cel_chunk(FILE* f, Sprite* sprite, frame_t frame, PixelFormat pixelFormat, FileOp* fop, ASE_Header* header, size_t chunk_end);
static void ase_file_write_cel_chunk(FILE* f, ASE_FrameHeader* frame_header, Cel* cel, LayerImage* layer, Sprite* sprite);
static void ase_file_write_cel_chunk(FILE* f, ASE_FrameHeader* frame_header, const Cel* cel, const LayerImage* layer, const Sprite* sprite);
static Mask* ase_file_read_mask_chunk(FILE* f);
#if 0
static void ase_file_write_mask_chunk(FILE* f, ASE_FrameHeader* frame_header, Mask* mask);
#endif
static void ase_file_read_frame_tags_chunk(FILE* f, FrameTags* frameTags);
static void ase_file_write_frame_tags_chunk(FILE* f, ASE_FrameHeader* frame_header, FrameTags* frameTags);
static void ase_file_write_frame_tags_chunk(FILE* f, ASE_FrameHeader* frame_header, const FrameTags* frameTags);
class ChunkWriter {
public:
@ -165,13 +165,13 @@ FileFormat* CreateAseFormat()
bool AseFormat::onLoad(FileOp* fop)
{
FileHandle handle(open_file_with_exception(fop->filename, "rb"));
FileHandle handle(open_file_with_exception(fop->filename(), "rb"));
FILE* f = handle.get();
bool ignore_old_color_chunks = false;
ASE_Header header;
if (!ase_file_read_header(f, &header)) {
fop_error(fop, "Error reading header\n");
fop->setError("Error reading header\n");
return false;
}
@ -195,7 +195,7 @@ bool AseFormat::onLoad(FileOp* fop)
for (frame_t frame(0); frame<sprite->totalFrames(); ++frame) {
// Start frame position
int frame_pos = ftell(f);
fop_progress(fop, (float)frame_pos / (float)header.size);
fop->setProgress((float)frame_pos / (float)header.size);
// Read frame header
ASE_FrameHeader frame_header;
@ -211,7 +211,7 @@ bool AseFormat::onLoad(FileOp* fop)
for (int c=0; c<frame_header.chunks; c++) {
/* start chunk position */
int chunk_pos = ftell(f);
fop_progress(fop, (float)chunk_pos / (float)header.size);
fop->setProgress((float)chunk_pos / (float)header.size);
// Read chunk information
int chunk_size = fgetl(f);
@ -244,7 +244,7 @@ bool AseFormat::onLoad(FileOp* fop)
}
case ASE_FILE_CHUNK_LAYER: {
/* fop_error(fop, "Layer chunk\n"); */
/* fop->setError("Layer chunk\n"); */
ase_file_read_layer_chunk(f, &header, sprite,
&last_layer,
@ -253,7 +253,7 @@ bool AseFormat::onLoad(FileOp* fop)
}
case ASE_FILE_CHUNK_CEL: {
/* fop_error(fop, "Cel chunk\n"); */
/* fop->setError("Cel chunk\n"); */
ase_file_read_cel_chunk(f, sprite, frame,
sprite->pixelFormat(), fop, &header,
@ -264,19 +264,19 @@ bool AseFormat::onLoad(FileOp* fop)
case ASE_FILE_CHUNK_MASK: {
Mask* mask;
/* fop_error(fop, "Mask chunk\n"); */
/* fop->setError("Mask chunk\n"); */
mask = ase_file_read_mask_chunk(f);
if (mask)
delete mask; // TODO add the mask in some place?
else
fop_error(fop, "Warning: error loading a mask chunk\n");
fop->setError("Warning: error loading a mask chunk\n");
break;
}
case ASE_FILE_CHUNK_PATH:
/* fop_error(fop, "Path chunk\n"); */
/* fop->setError("Path chunk\n"); */
break;
case ASE_FILE_CHUNK_FRAME_TAGS:
@ -284,7 +284,7 @@ bool AseFormat::onLoad(FileOp* fop)
break;
default:
fop_error(fop, "Warning: Unsupported chunk type %d (skipping)\n", chunk_type);
fop->setError("Warning: Unsupported chunk type %d (skipping)\n", chunk_type);
break;
}
@ -297,10 +297,10 @@ bool AseFormat::onLoad(FileOp* fop)
fseek(f, frame_pos+frame_header.size, SEEK_SET);
// Just one frame?
if (fop->oneframe)
if (fop->isOneFrame())
break;
if (fop_is_stop(fop))
if (fop->isStop())
break;
}
@ -308,7 +308,7 @@ bool AseFormat::onLoad(FileOp* fop)
sprite.release();
if (ferror(f)) {
fop_error(fop, "Error reading file.\n");
fop->setError("Error reading file.\n");
return false;
}
else {
@ -317,10 +317,11 @@ bool AseFormat::onLoad(FileOp* fop)
}
#ifdef ENABLE_SAVE
bool AseFormat::onSave(FileOp* fop)
{
Sprite* sprite = fop->document->sprite();
FileHandle handle(open_file_with_exception(fop->filename, "wb"));
const Sprite* sprite = fop->document()->sprite();
FileHandle handle(open_file_with_exception(fop->filename(), "wb"));
FILE* f = handle.get();
// Write the header
@ -382,9 +383,9 @@ bool AseFormat::onSave(FileOp* fop)
// Progress
if (sprite->totalFrames() > 1)
fop_progress(fop, float(frame+1) / float(sprite->totalFrames()));
fop->setProgress(float(frame+1) / float(sprite->totalFrames()));
if (fop_is_stop(fop))
if (fop->isStop())
break;
}
@ -392,14 +393,15 @@ bool AseFormat::onSave(FileOp* fop)
ase_file_write_header_filesize(f, &header);
if (ferror(f)) {
fop_error(fop, "Error writing file.\n");
fop->setError("Error writing file.\n");
return false;
}
else {
return true;
}
}
#endif
#endif // ENABLE_SAVE
static bool ase_file_read_header(FILE* f, ASE_Header* header)
{
@ -525,34 +527,34 @@ static void ase_file_write_frame_header(FILE* f, ASE_FrameHeader* frame_header)
fseek(f, end, SEEK_SET);
}
static void ase_file_write_layers(FILE* f, ASE_FrameHeader* frame_header, Layer* layer)
static void ase_file_write_layers(FILE* f, ASE_FrameHeader* frame_header, const Layer* layer)
{
ase_file_write_layer_chunk(f, frame_header, layer);
if (layer->isFolder()) {
LayerIterator it = static_cast<LayerFolder*>(layer)->getLayerBegin();
LayerIterator end = static_cast<LayerFolder*>(layer)->getLayerEnd();
auto it = static_cast<const LayerFolder*>(layer)->getLayerBegin(),
end = static_cast<const LayerFolder*>(layer)->getLayerEnd();
for (; it != end; ++it)
ase_file_write_layers(f, frame_header, *it);
}
}
static void ase_file_write_cels(FILE* f, ASE_FrameHeader* frame_header, Sprite* sprite, Layer* layer, frame_t frame)
static void ase_file_write_cels(FILE* f, ASE_FrameHeader* frame_header, const Sprite* sprite, const Layer* layer, frame_t frame)
{
if (layer->isImage()) {
Cel* cel = layer->cel(frame);
const Cel* cel = layer->cel(frame);
if (cel) {
/* fop_error(fop, "New cel in frame %d, in layer %d\n", */
/* fop->setError("New cel in frame %d, in layer %d\n", */
/* frame, sprite_layer2index(sprite, layer)); */
ase_file_write_cel_chunk(f, frame_header, cel, static_cast<LayerImage*>(layer), sprite);
ase_file_write_cel_chunk(f, frame_header, cel, static_cast<const LayerImage*>(layer), sprite);
}
}
if (layer->isFolder()) {
LayerIterator it = static_cast<LayerFolder*>(layer)->getLayerBegin();
LayerIterator end = static_cast<LayerFolder*>(layer)->getLayerEnd();
auto it = static_cast<const LayerFolder*>(layer)->getLayerBegin(),
end = static_cast<const LayerFolder*>(layer)->getLayerEnd();
for (; it != end; ++it)
ase_file_write_cels(f, frame_header, sprite, *it, frame);
@ -700,7 +702,7 @@ static Palette* ase_file_read_palette_chunk(FILE* f, Palette* prevPal, frame_t f
return pal;
}
static void ase_file_write_color2_chunk(FILE* f, ASE_FrameHeader* frame_header, Palette* pal)
static void ase_file_write_color2_chunk(FILE* f, ASE_FrameHeader* frame_header, const Palette* pal)
{
ChunkWriter chunk(f, frame_header, ASE_FILE_CHUNK_FLI_COLOR2);
int c, color;
@ -718,7 +720,7 @@ static void ase_file_write_color2_chunk(FILE* f, ASE_FrameHeader* frame_header,
}
}
static void ase_file_write_palette_chunk(FILE* f, ASE_FrameHeader* frame_header, Palette* pal, int from, int to)
static void ase_file_write_palette_chunk(FILE* f, ASE_FrameHeader* frame_header, const Palette* pal, int from, int to)
{
ChunkWriter chunk(f, frame_header, ASE_FILE_CHUNK_PALETTE);
@ -795,7 +797,7 @@ static Layer* ase_file_read_layer_chunk(FILE* f, ASE_Header* header, Sprite* spr
return layer;
}
static void ase_file_write_layer_chunk(FILE* f, ASE_FrameHeader* frame_header, Layer* layer)
static void ase_file_write_layer_chunk(FILE* f, ASE_FrameHeader* frame_header, const Layer* layer)
{
ChunkWriter chunk(f, frame_header, ASE_FILE_CHUNK_LAYER);
@ -817,8 +819,8 @@ static void ase_file_write_layer_chunk(FILE* f, ASE_FrameHeader* frame_header, L
// Default width & height, and blend mode
fputw(0, f);
fputw(0, f);
fputw(layer->isImage() ? (int)static_cast<LayerImage*>(layer)->blendMode(): 0, f);
fputc(layer->isImage() ? (int)static_cast<LayerImage*>(layer)->opacity(): 0, f);
fputw(layer->isImage() ? (int)static_cast<const LayerImage*>(layer)->blendMode(): 0, f);
fputc(layer->isImage() ? (int)static_cast<const LayerImage*>(layer)->opacity(): 0, f);
// padding
ase_file_write_padding(f, 3);
@ -826,7 +828,7 @@ static void ase_file_write_layer_chunk(FILE* f, ASE_FrameHeader* frame_header, L
/* layer name */
ase_file_write_string(f, layer->name());
/* fop_error(fop, "Layer name \"%s\" child level: %d\n", layer->name, child_level); */
/* fop->setError("Layer name \"%s\" child level: %d\n", layer->name, child_level); */
}
//////////////////////////////////////////////////////////////////////
@ -945,12 +947,12 @@ static void read_raw_image(FILE* f, Image* image, FileOp* fop, ASE_Header* heade
for (x=0; x<image->width(); x++)
put_pixel_fast<ImageTraits>(image, x, y, pixel_io.read_pixel(f));
fop_progress(fop, (float)ftell(f) / (float)header->size);
fop->setProgress((float)ftell(f) / (float)header->size);
}
}
template<typename ImageTraits>
static void write_raw_image(FILE* f, Image* image)
static void write_raw_image(FILE* f, const Image* image)
{
PixelIO<ImageTraits> pixel_io;
int x, y;
@ -1021,7 +1023,7 @@ static void read_compressed_image(FILE* f, Image* image, size_t chunk_end, FileO
}
} while (zstream.avail_out == 0);
fop_progress(fop, (float)ftell(f) / (float)header->size);
fop->setProgress((float)ftell(f) / (float)header->size);
}
uncompressed_offset = 0;
@ -1040,7 +1042,7 @@ static void read_compressed_image(FILE* f, Image* image, size_t chunk_end, FileO
}
template<typename ImageTraits>
static void write_compressed_image(FILE* f, Image* image)
static void write_compressed_image(FILE* f, const Image* image)
{
PixelIO<ImageTraits> pixel_io;
z_stream zstream;
@ -1109,13 +1111,13 @@ static Cel* ase_file_read_cel_chunk(FILE* f, Sprite* sprite, frame_t frame,
layer = sprite->indexToLayer(layer_index);
if (!layer) {
fop_error(fop, "Frame %d didn't found layer with index %d\n",
(int)frame, (int)layer_index);
fop->setError("Frame %d didn't found layer with index %d\n",
(int)frame, (int)layer_index);
return NULL;
}
if (!layer->isImage()) {
fop_error(fop, "Invalid .ase file (frame %d in layer %d which does not contain images\n",
(int)frame, (int)layer_index);
fop->setError("Invalid .ase file (frame %d in layer %d which does not contain images\n",
(int)frame, (int)layer_index);
return NULL;
}
@ -1210,7 +1212,7 @@ static Cel* ase_file_read_cel_chunk(FILE* f, Sprite* sprite, frame_t frame,
// OK, in case of error we can show the problem, but continue
// loading more cels.
catch (const std::exception& e) {
fop_error(fop, e.what());
fop->setError(e.what());
}
cel.reset(new Cel(frame, image));
@ -1229,12 +1231,13 @@ static Cel* ase_file_read_cel_chunk(FILE* f, Sprite* sprite, frame_t frame,
return cel.release();
}
static void ase_file_write_cel_chunk(FILE* f, ASE_FrameHeader* frame_header, Cel* cel, LayerImage* layer, Sprite* sprite)
static void ase_file_write_cel_chunk(FILE* f, ASE_FrameHeader* frame_header,
const Cel* cel, const LayerImage* layer, const Sprite* sprite)
{
ChunkWriter chunk(f, frame_header, ASE_FILE_CHUNK_CEL);
int layer_index = sprite->layerToIndex(layer);
Cel* link = cel->link();
const Cel* link = cel->link();
int cel_type = (link ? ASE_FILE_LINK_CEL: ASE_FILE_COMPRESSED_CEL);
fputw(layer_index, f);
@ -1247,7 +1250,7 @@ static void ase_file_write_cel_chunk(FILE* f, ASE_FrameHeader* frame_header, Cel
switch (cel_type) {
case ASE_FILE_RAW_CEL: {
Image* image = cel->image();
const Image* image = cel->image();
if (image) {
// Width and height
@ -1284,7 +1287,7 @@ static void ase_file_write_cel_chunk(FILE* f, ASE_FrameHeader* frame_header, Cel
break;
case ASE_FILE_COMPRESSED_CEL: {
Image* image = cel->image();
const Image* image = cel->image();
if (image) {
// Width and height
@ -1409,7 +1412,7 @@ static void ase_file_read_frame_tags_chunk(FILE* f, FrameTags* frameTags)
}
}
static void ase_file_write_frame_tags_chunk(FILE* f, ASE_FrameHeader* frame_header, FrameTags* frameTags)
static void ase_file_write_frame_tags_chunk(FILE* f, ASE_FrameHeader* frame_header, const FrameTags* frameTags)
{
ChunkWriter chunk(f, frame_header, ASE_FILE_CHUNK_FRAME_TAGS);
@ -1418,7 +1421,7 @@ static void ase_file_write_frame_tags_chunk(FILE* f, ASE_FrameHeader* frame_head
fputl(0, f); // 8 reserved bytes
fputl(0, f);
for (FrameTag* tag : *frameTags) {
for (const FrameTag* tag : *frameTags) {
fputw(tag->fromFrame(), f);
fputw(tag->toFrame(), f);
fputc((int)tag->aniDir(), f);

View File

@ -182,7 +182,7 @@ static int read_os2_bminfoheader(FILE *f, BITMAPINFOHEADER *infoheader)
/* read_bmicolors:
* Loads the color palette for 1,4,8 bit formats.
*/
static void read_bmicolors(FileOp *fop, int bytes, FILE *f, bool win_flag)
static void read_bmicolors(FileOp* fop, int bytes, FILE *f, bool win_flag)
{
int i, j, r, g, b;
@ -191,7 +191,7 @@ static void read_bmicolors(FileOp *fop, int bytes, FILE *f, bool win_flag)
g = fgetc(f);
r = fgetc(f);
fop_sequence_set_color(fop, j, r, g, b);
fop->sequenceSetColor(j, r, g, b);
j++;
i += 3;
@ -362,8 +362,8 @@ static void read_image(FILE *f, Image *image, const BITMAPINFOHEADER *infoheader
case 32: read_32bit_line(infoheader->biWidth, f, image, line); break;
}
fop_progress(fop, (float)(i+1) / (float)(height));
if (fop_is_stop(fop))
fop->setProgress((float)(i+1) / (float)(height));
if (fop->isStop())
break;
}
}
@ -602,7 +602,7 @@ bool BmpFormat::onLoad(FileOp *fop)
PixelFormat pixelFormat;
int format;
FileHandle handle(open_file_with_exception(fop->filename, "rb"));
FileHandle handle(open_file_with_exception(fop->filename(), "rb"));
FILE* f = handle.get();
if (read_bmfileheader(f, &fileheader) != 0)
@ -649,7 +649,7 @@ bool BmpFormat::onLoad(FileOp *fop)
else
rmask = gmask = bmask = 0;
Image* image = fop_sequence_image(fop, pixelFormat,
Image* image = fop->sequenceImage(pixelFormat,
infoheader.biWidth,
ABS((int)infoheader.biHeight));
if (!image) {
@ -677,23 +677,23 @@ bool BmpFormat::onLoad(FileOp *fop)
case BI_BITFIELDS:
if (read_bitfields_image(f, image, &infoheader, rmask, gmask, bmask) < 0) {
fop_error(fop, "Unsupported bitfields in the BMP file.\n");
fop->setError("Unsupported bitfields in the BMP file.\n");
return false;
}
break;
default:
fop_error(fop, "Unsupported BMP compression.\n");
fop->setError("Unsupported BMP compression.\n");
return false;
}
if (ferror(f)) {
fop_error(fop, "Error reading file.\n");
fop->setError("Error reading file.\n");
return false;
}
// Setup the file-data.
if (!fop->seq.format_options) {
if (!fop->sequenceGetFormatOptions()) {
base::SharedPtr<BmpOptions> bmp_options(new BmpOptions());
bmp_options->format = format;
@ -703,7 +703,7 @@ bool BmpFormat::onLoad(FileOp *fop)
bmp_options->green_mask = gmask;
bmp_options->blue_mask = bmask;
fop_sequence_set_format_options(fop, bmp_options);
fop->sequenceSetFormatOptions(bmp_options);
}
return true;
@ -712,7 +712,7 @@ bool BmpFormat::onLoad(FileOp *fop)
#ifdef ENABLE_SAVE
bool BmpFormat::onSave(FileOp *fop)
{
Image* image = fop->seq.image.get();
const Image* image = fop->sequenceImage();
int bfSize;
int biSizeImage;
int bpp = (image->pixelFormat() == IMAGE_RGB) ? 24 : 8;
@ -730,7 +730,7 @@ bool BmpFormat::onSave(FileOp *fop)
bfSize = 54 + biSizeImage; /* header + image data */
}
FileHandle handle(open_file_with_exception(fop->filename, "wb"));
FileHandle handle(open_file_with_exception(fop->filename(), "wb"));
FILE* f = handle.get();
/* file_header */
@ -761,7 +761,7 @@ bool BmpFormat::onSave(FileOp *fop)
/* palette */
for (i=0; i<256; i++) {
fop_sequence_get_color(fop, i, &r, &g, &b);
fop->sequenceGetColor(i, &r, &g, &b);
fputc(b, f);
fputc(g, f);
fputc(r, f);
@ -793,11 +793,11 @@ bool BmpFormat::onSave(FileOp *fop)
for (j=0; j<filler; j++)
fputc(0, f);
fop_progress(fop, (float)(image->height()-i) / (float)image->height());
fop->setProgress((float)(image->height()-i) / (float)image->height());
}
if (ferror(f)) {
fop_error(fop, "Error writing file.\n");
fop->setError("Error writing file.\n");
return false;
}
else {

File diff suppressed because it is too large Load Diff

View File

@ -9,6 +9,7 @@
#define APP_FILE_FILE_H_INCLUDED
#pragma once
#include "base/mutex.h"
#include "base/shared_ptr.h"
#include "doc/frame.h"
#include "doc/image_ref.h"
@ -23,10 +24,6 @@
#define FILE_LOAD_SEQUENCE_YES 0x00000004
#define FILE_LOAD_ONE_FRAME 0x00000008
namespace base {
class mutex;
}
namespace doc {
class Document;
}
@ -62,24 +59,84 @@ namespace app {
};
// Structure to load & save files.
struct FileOp {
FileOpType type; // Operation type: 0=load, 1=save.
FileFormat* format;
void* format_data; // Custom data for the FileFormat::onLoad/onSave operations.
Context* context;
Document* document; // Loaded document, or document to be saved.
std::string filename; // File-name to load/save.
class FileOp {
public:
static FileOp* createLoadDocumentOperation(Context* context, const char* filename, int flags);
static FileOp* createSaveDocumentOperation(const Context* context, const Document* document, const char* filename, const char* fn_format);
~FileOp();
bool isSequence() const { return !m_seq.filename_list.empty(); }
bool isOneFrame() const { return m_oneframe; }
const std::string& filename() const { return m_filename; }
Context* context() const { return m_context; }
Document* document() const { return m_document; }
Document* releaseDocument() {
Document* doc = m_document;
m_document = nullptr;
return doc;
}
void createDocument(Sprite* spr);
void operate(IFileOpProgress* progress = nullptr);
void done();
void stop();
bool isDone() const;
bool isStop() const;
// Does extra post-load processing which may require user intervention.
void postLoad();
// Helpers for file decoder/encoder (FileFormat) with
// FILE_SUPPORT_SEQUENCES flag.
base::SharedPtr<FormatOptions> sequenceGetFormatOptions() const;
void sequenceSetFormatOptions(const base::SharedPtr<FormatOptions>& formatOptions);
void sequenceSetNColors(int ncolors);
int sequenceGetNColors() const;
void sequenceSetColor(int index, int r, int g, int b);
void sequenceGetColor(int index, int* r, int* g, int* b) const;
void sequenceSetAlpha(int index, int a);
void sequenceGetAlpha(int index, int* a) const;
Image* sequenceImage(PixelFormat pixelFormat, int w, int h);
const Image* sequenceImage() const { return m_seq.image.get(); }
bool sequenceGetHasAlpha() const {
return m_seq.has_alpha;
}
void sequenceSetHasAlpha(bool hasAlpha) {
m_seq.has_alpha = hasAlpha;
}
const std::string& error() const { return m_error; }
void setError(const char *error, ...);
bool hasError() const { return !m_error.empty(); }
double progress() const;
void setProgress(double progress);
private:
FileOp(); // Undefined
FileOp(FileOpType type, Context* context);
FileOpType m_type; // Operation type: 0=load, 1=save.
FileFormat* m_format;
Context* m_context;
// TODO this should be a shared pointer (and we should remove
// releaseDocument() member function)
Document* m_document; // Loaded document, or document to be saved.
std::string m_filename; // File-name to load/save.
// Shared fields between threads.
base::mutex* mutex; // Mutex to access to the next two fields.
double progress; // Progress (1.0 is ready).
IFileOpProgress* progressInterface;
std::string error; // Error string.
bool done; // True if the operation finished.
bool stop; // Force the break of the operation.
bool oneframe; // Load just one frame (in formats
// that support animation like
// GIF/FLI/ASE).
mutable base::mutex m_mutex; // Mutex to access to the next two fields.
double m_progress; // Progress (1.0 is ready).
IFileOpProgress* m_progressInterface;
std::string m_error; // Error string.
bool m_done; // True if the operation finished.
bool m_stop; // Force the break of the operation.
bool m_oneframe; // Load just one frame (in formats
// that support animation like
// GIF/FLI/ASE).
// Data for sequences.
struct {
@ -95,19 +152,9 @@ namespace app {
LayerImage* layer;
Cel* last_cel;
base::SharedPtr<FormatOptions> format_options;
} seq;
} 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<FormatOptions>& format_options);
void fop_sequence_set_ncolors(FileOp* fop, int ncolors);
int fop_sequence_get_ncolors(FileOp* fop);
void fop_sequence_set_color(FileOp* fop, int index, int r, int g, int b);
void fop_sequence_get_color(FileOp* fop, int index, int *r, int *g, int *b);
void fop_sequence_set_alpha(FileOp* fop, int index, int a);
void fop_sequence_get_alpha(FileOp* fop, int index, int* a);
Image* fop_sequence_image(FileOp* fi, PixelFormat pixelFormat, int w, int h);
void fop_error(FileOp* fop, const char *error, ...);
void fop_progress(FileOp* fop, double progress);
double fop_get_progress(FileOp* fop);
bool fop_is_done(FileOp* fop);
bool fop_is_stop(FileOp* fop);
} // namespace app
#endif

View File

@ -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

View File

@ -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

View File

@ -212,15 +212,15 @@ public:
readRecord(recType);
// Just one frame?
if (m_fop->oneframe && m_frameNum > 0)
if (m_fop->isOneFrame() && m_frameNum > 0)
break;
if (fop_is_stop(m_fop))
if (m_fop->isStop())
break;
if (m_filesize > 0) {
int pos = posix_lseek(m_fd, 0, SEEK_CUR);
fop_progress(m_fop, double(pos) / double(m_filesize));
m_fop->setProgress(double(pos) / double(m_filesize));
}
}
@ -785,12 +785,12 @@ bool GifFormat::onLoad(FileOp* fop)
{
// The filesize is used only to report some progress when we decode
// the GIF file.
int filesize = base::file_size(fop->filename);
int filesize = base::file_size(fop->filename());
#if GIFLIB_MAJOR >= 5
int errCode = 0;
#endif
int fd = open_file_descriptor_with_exception(fop->filename, "rb");
int fd = open_file_descriptor_with_exception(fop->filename(), "rb");
GifFilePtr gif_file(DGifOpenFileHandle(fd
#if GIFLIB_MAJOR >= 5
, &errCode
@ -798,7 +798,7 @@ bool GifFormat::onLoad(FileOp* fop)
), &DGifCloseFile);
if (!gif_file) {
fop_error(fop, "Error loading GIF header.\n");
fop->setError("Error loading GIF header.\n");
return false;
}
@ -818,7 +818,7 @@ public:
GifEncoder(FileOp* fop, GifFileType* gifFile)
: m_fop(fop)
, m_gifFile(gifFile)
, m_sprite(fop->document->sprite())
, m_sprite(fop->document()->sprite())
, m_spriteBounds(m_sprite->bounds())
, m_hasBackground(m_sprite->backgroundLayer() ? true: false)
, m_bitsPerPixel(1)
@ -849,7 +849,7 @@ public:
else
m_clearColor = rgba(0, 0, 0, 0);
base::SharedPtr<GifOptions> gifOptions = fop->seq.format_options;
const base::SharedPtr<GifOptions> gifOptions = fop->sequenceGetFormatOptions();
m_interlaced = gifOptions->interlaced();
m_loop = (gifOptions->loop() ? 0: -1);
@ -905,7 +905,7 @@ public:
frameBounds,
m_clearColor);
fop_progress(m_fop, double(frameNum+1) / double(nframes));
m_fop->setProgress(double(frameNum+1) / double(nframes));
}
return true;
}
@ -1240,7 +1240,7 @@ private:
FileOp* m_fop;
GifFileType* m_gifFile;
Sprite* m_sprite;
const Sprite* m_sprite;
gfx::Rect m_spriteBounds;
bool m_hasBackground;
int m_bgIndex;
@ -1262,7 +1262,7 @@ bool GifFormat::onSave(FileOp* fop)
#if GIFLIB_MAJOR >= 5
int errCode = 0;
#endif
GifFilePtr gif_file(EGifOpenFileHandle(open_file_descriptor_with_exception(fop->filename, "wb")
GifFilePtr gif_file(EGifOpenFileHandle(open_file_descriptor_with_exception(fop->filename(), "wb")
#if GIFLIB_MAJOR >= 5
, &errCode
#endif
@ -1280,14 +1280,15 @@ bool GifFormat::onSave(FileOp* fop)
base::SharedPtr<FormatOptions> GifFormat::onGetFormatOptions(FileOp* fop)
{
base::SharedPtr<GifOptions> gif_options;
if (fop->document->getFormatOptions())
gif_options = base::SharedPtr<GifOptions>(fop->document->getFormatOptions());
if (fop->document()->getFormatOptions())
gif_options = base::SharedPtr<GifOptions>(fop->document()->getFormatOptions());
if (!gif_options)
gif_options.reset(new GifOptions);
// Non-interactive mode
if (!fop->context || !fop->context->isUIAvailable())
if (!fop->context() ||
!fop->context()->isUIAvailable())
return gif_options;
try {

View File

@ -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

View File

@ -92,7 +92,7 @@ static void output_message(j_common_ptr cinfo)
LOG("JPEG library: \"%s\"\n", buffer);
// Leave the message for the application.
fop_error(((struct error_mgr *)cinfo->err)->fop, "%s\n", buffer);
((struct error_mgr *)cinfo->err)->fop->setError("%s\n", buffer);
}
bool JpegFormat::onLoad(FileOp* fop)
@ -104,7 +104,7 @@ bool JpegFormat::onLoad(FileOp* fop)
JDIMENSION buffer_height;
int c;
FileHandle handle(open_file_with_exception(fop->filename, "rb"));
FileHandle handle(open_file_with_exception(fop->filename(), "rb"));
FILE* file = handle.get();
// Initialize the JPEG decompression object with error handling.
@ -137,11 +137,11 @@ bool JpegFormat::onLoad(FileOp* fop)
jpeg_start_decompress(&cinfo);
// Create the image.
Image* image = fop_sequence_image(fop,
(cinfo.out_color_space == JCS_RGB ? IMAGE_RGB:
IMAGE_GRAYSCALE),
cinfo.output_width,
cinfo.output_height);
Image* image = fop->sequenceImage(
(cinfo.out_color_space == JCS_RGB ? IMAGE_RGB:
IMAGE_GRAYSCALE),
cinfo.output_width,
cinfo.output_height);
if (!image) {
jpeg_destroy_decompress(&cinfo);
return false;
@ -170,7 +170,7 @@ bool JpegFormat::onLoad(FileOp* fop)
// Generate a grayscale palette if is necessary.
if (image->pixelFormat() == IMAGE_GRAYSCALE)
for (c=0; c<256; c++)
fop_sequence_set_color(fop, c, c, c, c);
fop->sequenceSetColor(c, c, c, c);
// Read each scan line.
while (cinfo.output_scanline < cinfo.output_height) {
@ -213,8 +213,8 @@ bool JpegFormat::onLoad(FileOp* fop)
}
}
fop_progress(fop, (float)(cinfo.output_scanline+1) / (float)(cinfo.output_height));
if (fop_is_stop(fop))
fop->setProgress((float)(cinfo.output_scanline+1) / (float)(cinfo.output_height));
if (fop->isStop())
break;
}
@ -234,14 +234,15 @@ bool JpegFormat::onSave(FileOp* fop)
{
struct jpeg_compress_struct cinfo;
struct error_mgr jerr;
Image* image = fop->seq.image.get();
const Image* image = fop->sequenceImage();
JSAMPARRAY buffer;
JDIMENSION buffer_height;
base::SharedPtr<JpegOptions> jpeg_options = fop->seq.format_options;
const base::SharedPtr<JpegOptions> jpeg_options =
fop->sequenceGetFormatOptions();
int c;
// Open the file for write in it.
FileHandle handle(open_file_with_exception(fop->filename, "wb"));
FileHandle handle(open_file_with_exception(fop->filename(), "wb"));
FILE* file = handle.get();
// Allocate and initialize JPEG compression object.
@ -277,7 +278,7 @@ bool JpegFormat::onSave(FileOp* fop)
buffer_height = 1;
buffer = (JSAMPARRAY)base_malloc(sizeof(JSAMPROW) * buffer_height);
if (!buffer) {
fop_error(fop, "Not enough memory for the buffer.\n");
fop->setError("Not enough memory for the buffer.\n");
jpeg_destroy_compress(&cinfo);
return false;
}
@ -286,7 +287,7 @@ bool JpegFormat::onSave(FileOp* fop)
buffer[c] = (JSAMPROW)base_malloc(sizeof(JSAMPLE) *
cinfo.image_width * cinfo.num_components);
if (!buffer[c]) {
fop_error(fop, "Not enough memory for buffer scanlines.\n");
fop->setError("Not enough memory for buffer scanlines.\n");
for (c--; c>=0; c--)
base_free(buffer[c]);
base_free(buffer);
@ -328,7 +329,7 @@ bool JpegFormat::onSave(FileOp* fop)
}
jpeg_write_scanlines(&cinfo, buffer, buffer_height);
fop_progress(fop, (float)(cinfo.next_scanline+1) / (float)(cinfo.image_height));
fop->setProgress((float)(cinfo.next_scanline+1) / (float)(cinfo.image_height));
}
// Destroy all data.
@ -351,14 +352,15 @@ bool JpegFormat::onSave(FileOp* fop)
base::SharedPtr<FormatOptions> JpegFormat::onGetFormatOptions(FileOp* fop)
{
base::SharedPtr<JpegOptions> jpeg_options;
if (fop->document->getFormatOptions())
jpeg_options = base::SharedPtr<JpegOptions>(fop->document->getFormatOptions());
if (fop->document()->getFormatOptions())
jpeg_options = base::SharedPtr<JpegOptions>(fop->document()->getFormatOptions());
if (!jpeg_options)
jpeg_options.reset(new JpegOptions);
// Non-interactive mode
if (!fop->context || !fop->context->isUIAvailable())
if (!fop->context() ||
!fop->context()->isUIAvailable())
return jpeg_options;
try {

View File

@ -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<FileOp> 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();
}
}
}

View File

@ -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 {

View File

@ -56,7 +56,7 @@ FileFormat* CreatePngFormat()
static void report_png_error(png_structp png_ptr, png_const_charp error)
{
fop_error((FileOp*)png_get_error_ptr(png_ptr), "libpng: %s\n", error);
((FileOp*)png_get_error_ptr(png_ptr))->setError("libpng: %s\n", error);
}
bool PngFormat::onLoad(FileOp* fop)
@ -72,7 +72,7 @@ bool PngFormat::onLoad(FileOp* fop)
png_bytep row_pointer;
PixelFormat pixelFormat;
FileHandle handle(open_file_with_exception(fop->filename, "rb"));
FileHandle handle(open_file_with_exception(fop->filename(), "rb"));
FILE* fp = handle.get();
/* Create and initialize the png_struct with the desired error handler
@ -84,14 +84,14 @@ bool PngFormat::onLoad(FileOp* fop)
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)fop,
report_png_error, report_png_error);
if (png_ptr == NULL) {
fop_error(fop, "png_create_read_struct\n");
fop->setError("png_create_read_struct\n");
return false;
}
/* Allocate/initialize the memory for image information. */
info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == NULL) {
fop_error(fop, "png_create_info_struct\n");
fop->setError("png_create_info_struct\n");
png_destroy_read_struct(&png_ptr, NULL, NULL);
return false;
}
@ -100,7 +100,7 @@ bool PngFormat::onLoad(FileOp* fop)
* the normal method of doing things with libpng).
*/
if (setjmp(png_jmpbuf(png_ptr))) {
fop_error(fop, "Error reading PNG file\n");
fop->setError("Error reading PNG file\n");
/* Free all of the memory associated with the png_ptr and info_ptr */
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
/* If we get here, we had a problem reading the file */
@ -155,13 +155,13 @@ bool PngFormat::onLoad(FileOp* fop)
switch (png_get_color_type(png_ptr, info_ptr)) {
case PNG_COLOR_TYPE_RGB_ALPHA:
fop->seq.has_alpha = true;
fop->sequenceSetHasAlpha(true);
case PNG_COLOR_TYPE_RGB:
pixelFormat = IMAGE_RGB;
break;
case PNG_COLOR_TYPE_GRAY_ALPHA:
fop->seq.has_alpha = true;
fop->sequenceSetHasAlpha(true);
case PNG_COLOR_TYPE_GRAY:
pixelFormat = IMAGE_GRAYSCALE;
break;
@ -171,16 +171,16 @@ bool PngFormat::onLoad(FileOp* fop)
break;
default:
fop_error(fop, "Color type not supported\n)");
fop->setError("Color type not supported\n)");
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return false;
}
int imageWidth = png_get_image_width(png_ptr, info_ptr);
int imageHeight = png_get_image_height(png_ptr, info_ptr);
Image* image = fop_sequence_image(fop, pixelFormat, imageWidth, imageHeight);
Image* image = fop->sequenceImage(pixelFormat, imageWidth, imageHeight);
if (!image) {
fop_error(fop, "file_sequence_image %dx%d\n", imageWidth, imageHeight);
fop->setError("file_sequence_image %dx%d\n", imageWidth, imageHeight);
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return false;
}
@ -191,13 +191,13 @@ bool PngFormat::onLoad(FileOp* fop)
// Read the palette
if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_PALETTE &&
png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette)) {
fop_sequence_set_ncolors(fop, num_palette);
fop->sequenceSetNColors(num_palette);
for (int c=0; c<num_palette; ++c) {
fop_sequence_set_color(fop, c,
palette[c].red,
palette[c].green,
palette[c].blue);
fop->sequenceSetColor(c,
palette[c].red,
palette[c].green,
palette[c].blue);
}
// Read alpha values for palette entries
@ -208,10 +208,10 @@ bool PngFormat::onLoad(FileOp* fop)
png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, nullptr);
for (int i = 0; i < num_trans; ++i) {
fop_sequence_set_alpha(fop, i, trans[i]);
fop->sequenceSetAlpha(i, trans[i]);
if (trans[i] < 255) {
fop->seq.has_alpha = true; // Is a transparent sprite
fop->sequenceSetHasAlpha(true); // Is a transparent sprite
if (trans[i] == 0) {
if (mask_entry < 0)
mask_entry = i;
@ -220,7 +220,7 @@ bool PngFormat::onLoad(FileOp* fop)
}
if (mask_entry >= 0)
fop->document->sprite()->setTransparentColor(mask_entry);
fop->document()->sprite()->setTransparentColor(mask_entry);
}
else {
png_get_tRNS(png_ptr, info_ptr, nullptr, nullptr, &png_trans_color);
@ -264,8 +264,8 @@ bool PngFormat::onLoad(FileOp* fop)
g == png_trans_color->green &&
b == png_trans_color->blue) {
a = 0;
if (!fop->seq.has_alpha)
fop->seq.has_alpha = true;
if (!fop->sequenceGetHasAlpha())
fop->sequenceSetHasAlpha(true);
}
else
a = 255;
@ -298,8 +298,8 @@ bool PngFormat::onLoad(FileOp* fop)
if (png_trans_color &&
k == png_trans_color->gray) {
a = 0;
if (!fop->seq.has_alpha)
fop->seq.has_alpha = true;
if (!fop->sequenceGetHasAlpha())
fop->sequenceSetHasAlpha(true);
}
else
a = 255;
@ -317,11 +317,11 @@ bool PngFormat::onLoad(FileOp* fop)
*(dst_address++) = *(src_address++);
}
fop_progress(fop,
(double)((double)pass + (double)(y+1) / (double)(height))
/ (double)number_passes);
fop->setProgress(
(double)((double)pass + (double)(y+1) / (double)(height))
/ (double)number_passes);
if (fop_is_stop(fop))
if (fop->isStop())
break;
}
}
@ -335,7 +335,7 @@ bool PngFormat::onLoad(FileOp* fop)
#ifdef ENABLE_SAVE
bool PngFormat::onSave(FileOp* fop)
{
Image* image = fop->seq.image.get();
const Image* image = fop->sequenceImage();
png_uint_32 width, height, y;
png_structp png_ptr;
png_infop info_ptr;
@ -345,7 +345,7 @@ bool PngFormat::onSave(FileOp* fop)
int pass, number_passes;
/* open the file */
FileHandle handle(open_file_with_exception(fop->filename, "wb"));
FileHandle handle(open_file_with_exception(fop->filename(), "wb"));
FILE* fp = handle.get();
/* Create and initialize the png_struct with the desired error handler
@ -392,12 +392,12 @@ bool PngFormat::onSave(FileOp* fop)
switch (image->pixelFormat()) {
case IMAGE_RGB:
color_type = fop->document->sprite()->needAlpha() ?
color_type = fop->document()->sprite()->needAlpha() ?
PNG_COLOR_TYPE_RGB_ALPHA:
PNG_COLOR_TYPE_RGB;
break;
case IMAGE_GRAYSCALE:
color_type = fop->document->sprite()->needAlpha() ?
color_type = fop->document()->sprite()->needAlpha() ?
PNG_COLOR_TYPE_GRAY_ALPHA:
PNG_COLOR_TYPE_GRAY;
break;
@ -411,7 +411,7 @@ bool PngFormat::onSave(FileOp* fop)
if (image->pixelFormat() == IMAGE_INDEXED) {
int c, r, g, b;
int pal_size = fop_sequence_get_ncolors(fop);
int pal_size = fop->sequenceGetNColors();
pal_size = MID(1, pal_size, PNG_MAX_PALETTE_LENGTH);
#if PNG_MAX_PALETTE_LENGTH != 256
@ -421,7 +421,7 @@ bool PngFormat::onSave(FileOp* fop)
// Save the color palette.
palette = (png_colorp)png_malloc(png_ptr, pal_size * sizeof(png_color));
for (c = 0; c < pal_size; c++) {
fop_sequence_get_color(fop, c, &r, &g, &b);
fop->sequenceGetColor(c, &r, &g, &b);
palette[c].red = r;
palette[c].green = g;
palette[c].blue = b;
@ -432,9 +432,9 @@ bool PngFormat::onSave(FileOp* fop)
// If the sprite does not have a (visible) background layer, we
// put alpha=0 to the transparent color.
int mask_entry = -1;
if (fop->document->sprite()->backgroundLayer() == NULL ||
!fop->document->sprite()->backgroundLayer()->isVisible()) {
mask_entry = fop->document->sprite()->transparentColor();
if (fop->document()->sprite()->backgroundLayer() == NULL ||
!fop->document()->sprite()->backgroundLayer()->isVisible()) {
mask_entry = fop->document()->sprite()->transparentColor();
}
int num_trans = pal_size;
@ -442,7 +442,7 @@ bool PngFormat::onSave(FileOp* fop)
for (c=0; c<num_trans; ++c) {
int alpha = 255;
fop_sequence_get_alpha(fop, c, &alpha);
fop->sequenceGetAlpha(c, &alpha);
trans[c] = (c == mask_entry ? 0: alpha);
}
@ -530,9 +530,9 @@ bool PngFormat::onSave(FileOp* fop)
/* write the line */
png_write_rows(png_ptr, &row_pointer, 1);
fop_progress(fop,
(double)((double)pass + (double)(y+1) / (double)(height))
/ (double)number_passes);
fop->setProgress(
(double)((double)pass + (double)(y+1) / (double)(height))
/ (double)number_passes);
}
}

View File

@ -197,7 +197,7 @@ bool TgaFormat::onLoad(FileOp* fop)
unsigned int c, i, x, y, yc;
int compressed;
FileHandle handle(open_file_with_exception(fop->filename, "rb"));
FileHandle handle(open_file_with_exception(fop->filename(), "rb"));
FILE* f = handle.get();
id_length = fgetc(f);
@ -264,10 +264,10 @@ bool TgaFormat::onLoad(FileOp* fop)
}
for (i=0; i<palette_colors; i++) {
fop_sequence_set_color(fop, i,
image_palette[i][2],
image_palette[i][1],
image_palette[i][0]);
fop->sequenceSetColor(i,
image_palette[i][2],
image_palette[i][1],
image_palette[i][0]);
}
pixelFormat = IMAGE_INDEXED;
@ -291,7 +291,7 @@ bool TgaFormat::onLoad(FileOp* fop)
}
for (i=0; i<256; i++)
fop_sequence_set_color(fop, i, i, i, i);
fop->sequenceSetColor(i, i, i, i);
pixelFormat = IMAGE_GRAYSCALE;
break;
@ -301,7 +301,7 @@ bool TgaFormat::onLoad(FileOp* fop)
return false;
}
Image* image = fop_sequence_image(fop, pixelFormat, image_width, image_height);
Image* image = fop->sequenceImage(pixelFormat, image_width, image_height);
if (!image)
return false;
@ -362,14 +362,14 @@ bool TgaFormat::onLoad(FileOp* fop)
}
if (image_height > 1) {
fop_progress(fop, (float)(image_height-y) / (float)(image_height));
if (fop_is_stop(fop))
fop->setProgress((float)(image_height-y) / (float)(image_height));
if (fop->isStop())
break;
}
}
if (ferror(f)) {
fop_error(fop, "Error reading file.\n");
fop->setError("Error reading file.\n");
return false;
}
else {
@ -382,13 +382,13 @@ bool TgaFormat::onLoad(FileOp* fop)
// should be an array of at least 256 RGB structures).
bool TgaFormat::onSave(FileOp* fop)
{
Image* image = fop->seq.image.get();
const Image* image = fop->sequenceImage();
unsigned char image_palette[256][3];
int x, y, c, r, g, b;
int depth = (image->pixelFormat() == IMAGE_RGB) ? 32 : 8;
bool need_pal = (image->pixelFormat() == IMAGE_INDEXED)? true: false;
FileHandle handle(open_file_with_exception(fop->filename, "wb"));
FileHandle handle(open_file_with_exception(fop->filename(), "wb"));
FILE* f = handle.get();
fputc(0, f); /* id length (no id saved) */
@ -411,7 +411,7 @@ bool TgaFormat::onSave(FileOp* fop)
if (need_pal) {
for (y=0; y<256; y++) {
fop_sequence_get_color(fop, y, &r, &g, &b);
fop->sequenceGetColor(y, &r, &g, &b);
image_palette[y][2] = r;
image_palette[y][1] = g;
image_palette[y][0] = b;
@ -431,7 +431,7 @@ bool TgaFormat::onSave(FileOp* fop)
fputc(rgba_geta(c), f);
}
fop_progress(fop, (float)(image->height()-y) / (float)(image->height()));
fop->setProgress((float)(image->height()-y) / (float)(image->height()));
}
break;
@ -440,7 +440,7 @@ bool TgaFormat::onSave(FileOp* fop)
for (x=0; x<image->width(); x++)
fputc(graya_getv(get_pixel(image, x, y)), f);
fop_progress(fop, (float)(image->height()-y) / (float)(image->height()));
fop->setProgress((float)(image->height()-y) / (float)(image->height()));
}
break;
@ -449,13 +449,13 @@ bool TgaFormat::onSave(FileOp* fop)
for (x=0; x<image->width(); x++)
fputc(get_pixel(image, x, y), f);
fop_progress(fop, (float)(image->height()-y) / (float)(image->height()));
fop->setProgress((float)(image->height()-y) / (float)(image->height()));
}
break;
}
if (ferror(f)) {
fop_error(fop, "Error writing file.\n");
fop->setError("Error writing file.\n");
return false;
}
else {

View File

@ -29,8 +29,7 @@
#include <algorithm>
#include <map>
//include webp librarys
// Include webp libraries
#include <webp/decode.h>
#include <webp/encode.h>
@ -65,27 +64,28 @@ FileFormat* CreateWebPFormat()
return new WebPFormat;
}
const char* getDecoderErrorMessage(VP8StatusCode statusCode) {
const char* getDecoderErrorMessage(VP8StatusCode statusCode)
{
switch (statusCode) {
case VP8_STATUS_OK: return ""; break;
case VP8_STATUS_OUT_OF_MEMORY: return "out of memory"; break;
case VP8_STATUS_INVALID_PARAM: return "invalid parameters"; break;
case VP8_STATUS_BITSTREAM_ERROR: return "bitstream error"; break;
case VP8_STATUS_UNSUPPORTED_FEATURE: return "unsupported feature"; break;
case VP8_STATUS_SUSPENDED: return "suspended"; break;
case VP8_STATUS_USER_ABORT: return "user aborted"; break;
case VP8_STATUS_NOT_ENOUGH_DATA: return "not enough data"; break;
default: return "unknown error"; break;
case VP8_STATUS_OK: return ""; break;
case VP8_STATUS_OUT_OF_MEMORY: return "out of memory"; break;
case VP8_STATUS_INVALID_PARAM: return "invalid parameters"; break;
case VP8_STATUS_BITSTREAM_ERROR: return "bitstream error"; break;
case VP8_STATUS_UNSUPPORTED_FEATURE: return "unsupported feature"; break;
case VP8_STATUS_SUSPENDED: return "suspended"; break;
case VP8_STATUS_USER_ABORT: return "user aborted"; break;
case VP8_STATUS_NOT_ENOUGH_DATA: return "not enough data"; break;
default: return "unknown error"; break;
}
}
bool WebPFormat::onLoad(FileOp* fop)
{
FileHandle handle(open_file_with_exception(fop->filename, "rb"));
FileHandle handle(open_file_with_exception(fop->filename(), "rb"));
FILE* fp = handle.get();
if (fseek(fp, 0, SEEK_END) != 0) {
fop_error(fop, "Error while getting WebP file size for %s\n", fop->filename.c_str());
fop->setError("Error while getting WebP file size for %s\n", fop->filename().c_str());
return false;
}
@ -93,7 +93,7 @@ bool WebPFormat::onLoad(FileOp* fop)
rewind(fp);
if (len < 4) {
fop_error(fop, "%s is corrupt or not a WebP file\n", fop->filename.c_str());
fop->setError("%s is corrupt or not a WebP file\n", fop->filename().c_str());
return false;
}
@ -101,24 +101,24 @@ bool WebPFormat::onLoad(FileOp* fop)
uint8_t* data = &buf.front();
if (!fread(data, sizeof(uint8_t), len, fp)) {
fop_error(fop, "Error while writing to %s to memory\n", fop->filename.c_str());
fop->setError("Error while writing to %s to memory\n", fop->filename().c_str());
return false;
}
WebPDecoderConfig config;
if (!WebPInitDecoderConfig(&config)) {
fop_error(fop, "LibWebP version mismatch %s\n", fop->filename.c_str());
fop->setError("LibWebP version mismatch %s\n", fop->filename().c_str());
return false;
}
if (WebPGetFeatures(data, len, &config.input) != VP8_STATUS_OK) {
fop_error(fop, "Bad bitstream in %s\n", fop->filename.c_str());
fop->setError("Bad bitstream in %s\n", fop->filename().c_str());
return false;
}
fop->seq.has_alpha = (config.input.has_alpha != 0);
fop->sequenceSetHasAlpha(config.input.has_alpha != 0);
Image* image = fop_sequence_image(fop, IMAGE_RGB, config.input.width, config.input.height);
Image* image = fop->sequenceImage(IMAGE_RGB, config.input.width, config.input.height);
config.output.colorspace = MODE_RGBA;
config.output.u.RGBA.rgba = (uint8_t*)image->getPixelAddress(0, 0);
@ -128,7 +128,7 @@ bool WebPFormat::onLoad(FileOp* fop)
WebPIDecoder* idec = WebPIDecode(NULL, 0, &config);
if (idec == NULL) {
fop_error(fop, "Error creating WebP decoder for %s\n", fop->filename.c_str());
fop->setError("Error creating WebP decoder for %s\n", fop->filename().c_str());
return false;
}
@ -141,19 +141,20 @@ bool WebPFormat::onLoad(FileOp* fop)
bytes_remaining -= bytes_read;
data += bytes_read;
if (bytes_remaining < bytes_read) bytes_read = bytes_remaining;
fop_progress(fop, 1.0f - ((float)std::max(bytes_remaining, 0l)/(float)len));
fop->setProgress(1.0f - ((float)std::max(bytes_remaining, 0l)/(float)len));
} else {
fop_error(fop, "Error during decoding %s : %s\n", fop->filename.c_str(), getDecoderErrorMessage(status));
fop->setError("Error during decoding %s : %s\n",
fop->filename().c_str(), getDecoderErrorMessage(status));
WebPIDelete(idec);
WebPFreeDecBuffer(&config.output);
return false;
}
if (fop_is_stop(fop))
if (fop->isStop())
break;
}
base::SharedPtr<WebPOptions> webPOptions = base::SharedPtr<WebPOptions>(new WebPOptions());
fop->seq.format_options = webPOptions;
fop->sequenceSetFormatOptions(webPOptions);
webPOptions->setLossless(std::min(config.input.format - 1, 1));
WebPIDelete(idec);
@ -162,7 +163,8 @@ bool WebPFormat::onLoad(FileOp* fop)
}
#ifdef ENABLE_SAVE
struct writerData {
struct WriterData {
FILE* fp;
FileOp* fop;
};
@ -206,57 +208,62 @@ int WebPConfigLosslessPreset(WebPConfig* config, int level) {
static int ProgressReport(int percent, const WebPPicture* const pic)
{
fop_progress(((writerData*)pic->custom_ptr)->fop, (double)percent/(double)100);
if (fop_is_stop(((writerData*)pic->custom_ptr)->fop)) return false;
return true;
FileOp* fop = ((WriterData*)pic->custom_ptr)->fop;
fop->setProgress((double)percent/(double)100);
if (fop->isStop())
return false;
else
return true;
}
static int FileWriter(const uint8_t* data, size_t data_size, const WebPPicture* const pic)
{
return data_size ? (fwrite(data, data_size, 1, ((writerData*)pic->custom_ptr)->fp) == 1) : 1;
return (data_size ? (fwrite(data, data_size, 1, ((WriterData*)pic->custom_ptr)->fp) == 1) : 1);
}
bool WebPFormat::onSave(FileOp* fop)
{
FileHandle handle(open_file_with_exception(fop->filename, "wb"));
FileHandle handle(open_file_with_exception(fop->filename(), "wb"));
FILE* fp = handle.get();
struct writerData wd = {fp, fop};
WriterData wd = { fp, fop };
Image* image = fop->seq.image.get();
if (image->width() > WEBP_MAX_DIMENSION || image->height() > WEBP_MAX_DIMENSION) {
fop_error(
fop, "Error: WebP can only have a maximum width and height of %i but your %s has a size of %i x %i\n",
WEBP_MAX_DIMENSION, fop->filename.c_str(), image->width(), image->height()
const Image* image = fop->sequenceImage();
if (image->width() > WEBP_MAX_DIMENSION ||
image->height() > WEBP_MAX_DIMENSION) {
fop->setError("Error: WebP can only have a maximum width and height of %i but your %s has a size of %i x %i\n",
WEBP_MAX_DIMENSION, fop->filename().c_str(), image->width(), image->height()
);
return false;
}
base::SharedPtr<WebPOptions> webp_options = fop->seq.format_options;
base::SharedPtr<WebPOptions> webp_options =
fop->sequenceGetFormatOptions();
WebPConfig config;
if (webp_options->lossless()) {
if (!(WebPConfigInit(&config) && WebPConfigLosslessPreset(&config, webp_options->getMethod()))) {
fop_error(fop, "Error for WebP Config Version for file %s\n", fop->filename.c_str());
return false;
fop->setError("Error for WebP Config Version for file %s\n", fop->filename().c_str());
return false;
}
config.image_hint = webp_options->getImageHint();
} else {
}
else {
if (!WebPConfigPreset(&config, webp_options->getImagePreset(), static_cast<float>(webp_options->getQuality()))) {
fop_error(fop, "Error for WebP Config Version for file %s\n", fop->filename.c_str());
return false;
fop->setError("Error for WebP Config Version for file %s\n", fop->filename().c_str());
return false;
}
}
if (!WebPValidateConfig(&config)) {
fop_error(fop, "Error in WebP Encoder Config for file %s\n", fop->filename.c_str());
return false;
fop->setError("Error in WebP Encoder Config for file %s\n", fop->filename().c_str());
return false;
}
WebPPicture pic;
if (!WebPPictureInit(&pic)) {
fop_error(fop, "Error for WebP Picture Version mismatch for file %s\n", fop->filename.c_str());
fop->setError("Error for WebP Picture Version mismatch for file %s\n", fop->filename().c_str());
return false;
}
@ -267,12 +274,12 @@ bool WebPFormat::onSave(FileOp* fop)
}
if (!WebPPictureAlloc(&pic)) {
fop_error(fop, "Error for WebP Picture memory allocations for file %s\n", fop->filename.c_str());
fop->setError("Error for WebP Picture memory allocations for file %s\n", fop->filename().c_str());
return false;
}
if (!WebPPictureImportRGBA(&pic, (uint8_t*)image->getPixelAddress(0, 0), image->width() * sizeof(uint32_t))) {
fop_error(fop, "Error for LibWebP Import RGBA Buffer into Picture for %s\n", fop->filename.c_str());
fop->setError("Error for LibWebP Import RGBA Buffer into Picture for %s\n", fop->filename().c_str());
WebPPictureFree(&pic);
return false;
}
@ -282,7 +289,8 @@ bool WebPFormat::onSave(FileOp* fop)
pic.progress_hook = ProgressReport;
if (!WebPEncode(&config, &pic)) {
fop_error(fop, "Error for LibWebP while Encoding %s: %s\n", fop->filename.c_str(), getEncoderErrorMessage(pic.error_code));
fop->setError("Error for LibWebP while Encoding %s: %s\n",
fop->filename().c_str(), getEncoderErrorMessage(pic.error_code));
WebPPictureFree(&pic);
return false;
}
@ -290,20 +298,22 @@ bool WebPFormat::onSave(FileOp* fop)
WebPPictureFree(&pic);
return true;
}
#endif
#endif // ENABLE_SAVE
// Shows the WebP configuration dialog.
base::SharedPtr<FormatOptions> WebPFormat::onGetFormatOptions(FileOp* fop)
{
base::SharedPtr<WebPOptions> webp_options;
if (fop->document->getFormatOptions())
webp_options = base::SharedPtr<WebPOptions>(fop->document->getFormatOptions());
if (fop->document()->getFormatOptions())
webp_options = base::SharedPtr<WebPOptions>(fop->document()->getFormatOptions());
if (!webp_options)
webp_options.reset(new WebPOptions);
// Non-interactive mode
if (!fop->context || !fop->context->isUIAvailable())
if (!fop->context() ||
!fop->context()->isUIAvailable())
return webp_options;
try {

View File

@ -42,29 +42,29 @@ public:
}
~Worker() {
fop_stop(m_fop);
m_fop->stop();
m_thread.join();
fop_free(m_fop);
}
IFileItem* getFileItem() { return m_fileitem; }
bool isDone() const { return fop_is_done(m_fop); }
double getProgress() const { return fop_get_progress(m_fop); }
bool isDone() const { return m_fop->isDone(); }
double getProgress() const { return m_fop->progress(); }
private:
void loadBgThread() {
try {
fop_operate(m_fop, NULL);
m_fop->operate(nullptr);
// Post load
fop_post_load(m_fop);
m_fop->postLoad();
// Convert the loaded document into the she::Surface.
const Sprite* sprite = (m_fop->document && m_fop->document->sprite()) ?
m_fop->document->sprite(): NULL;
const Sprite* sprite =
(m_fop->document() &&
m_fop->document()->sprite() ?
m_fop->document()->sprite(): nullptr);
if (!fop_is_stop(m_fop) && sprite) {
if (!m_fop->isStop() && sprite) {
// The palette to convert the Image
m_palette.reset(new Palette(*sprite->palette(frame_t(0))));
@ -96,7 +96,7 @@ private:
}
// Close file
delete m_fop->document;
delete m_fop->releaseDocument();
// Set the thumbnail of the file-item.
if (m_thumbnail) {
@ -111,12 +111,12 @@ private:
}
}
catch (const std::exception& e) {
fop_error(m_fop, "Error loading file:\n%s", e.what());
m_fop->setError("Error loading file:\n%s", e.what());
}
fop_done(m_fop);
m_fop->done();
}
FileOp* m_fop;
base::UniquePtr<FileOp> m_fop;
IFileItem* m_fileitem;
base::UniquePtr<Image> m_thumbnail;
base::UniquePtr<Palette> m_palette;
@ -185,27 +185,26 @@ void ThumbnailGenerator::addWorkerToGenerateThumbnail(IFileItem* fileitem)
getWorkerStatus(fileitem, progress) != WithoutWorker)
return;
FileOp* fop = fop_to_load_document(NULL,
fileitem->getFileName().c_str(),
FILE_LOAD_SEQUENCE_NONE |
FILE_LOAD_ONE_FRAME);
base::UniquePtr<FileOp> fop(
FileOp::createLoadDocumentOperation(
nullptr,
fileitem->getFileName().c_str(),
FILE_LOAD_SEQUENCE_NONE |
FILE_LOAD_ONE_FRAME));
if (!fop)
return;
if (fop->has_error()) {
fop_free(fop);
if (fop->hasError())
return;
Worker* worker = new Worker(fop.release(), fileitem);
try {
base::scoped_lock hold(m_workersAccess);
m_workers.push_back(worker);
}
else {
Worker* worker = new Worker(fop, fileitem);
try {
base::scoped_lock hold(m_workersAccess);
m_workers.push_back(worker);
}
catch (...) {
delete worker;
throw;
}
catch (...) {
delete worker;
throw;
}
}
@ -224,10 +223,8 @@ void ThumbnailGenerator::stopAllWorkersBackground()
m_workers.clear();
}
for (WorkerList::iterator
it=workersCopy.begin(), end=workersCopy.end(); it!=end; ++it) {
for (auto it=workersCopy.begin(), end=workersCopy.end(); it!=end; ++it)
delete *it;
}
}
} // namespace app