Add progress bar when a palette is created from a RGB file

This commit is contained in:
David Capello 2015-07-22 18:26:25 -03:00
parent 96080a378c
commit b35fc87ec1
5 changed files with 65 additions and 9 deletions

View File

@ -15,6 +15,7 @@
#include "app/console.h"
#include "app/context.h"
#include "app/context_access.h"
#include "app/job.h"
#include "app/modules/palettes.h"
#include "app/pref/preferences.h"
#include "app/transaction.h"
@ -41,6 +42,38 @@ protected:
void onExecute(Context* context) override;
};
class ColorQuantizationJob : public Job,
public render::PaletteOptimizerDelegate {
public:
ColorQuantizationJob(Sprite* sprite, bool withAlpha, Palette* palette)
: Job("Creating Palette")
, m_sprite(sprite)
, m_withAlpha(withAlpha)
, m_palette(palette) {
}
private:
void onJob() override {
render::create_palette_from_rgb(m_sprite,
0, m_sprite->lastFrame(),
m_withAlpha, m_palette,
this);
}
bool onPaletteOptimizerContinue() override {
return !isCanceled();
}
void onPaletteOptimizerProgress(double progress) override {
jobProgress(progress);
}
Sprite* m_sprite;
bool m_withAlpha;
Palette* m_palette;
};
ColorQuantizationCommand::ColorQuantizationCommand()
: Command("ColorQuantization",
"Color Quantization",
@ -114,8 +147,11 @@ void ColorQuantizationCommand::onExecute(Context* context)
return;
Palette tmpPalette(frame, entries.picks());
render::create_palette_from_rgb(sprite, 0, sprite->lastFrame(),
withAlpha, &tmpPalette);
ColorQuantizationJob job(sprite, withAlpha, &tmpPalette);
job.startJob();
job.waitJob();
if (job.isCanceled())
return;
base::UniquePtr<Palette> newPalette(
new Palette(createPal ? tmpPalette:

View File

@ -740,7 +740,8 @@ void fop_post_load(FileOp* fop)
sprite->palette(frame_t(0))->isBlack()) {
base::SharedPtr<Palette> palette(
render::create_palette_from_rgb(
sprite, frame_t(0), sprite->lastFrame(), true, nullptr));
sprite, frame_t(0), sprite->lastFrame(), true,
nullptr, nullptr));
sprite->resetPalettes();
sprite->setPalette(palette.get(), false);

View File

@ -1047,7 +1047,7 @@ private:
}
Palette* palette = new Palette(0, 256);
optimizer.calculate(palette, m_transparentIndex);
optimizer.calculate(palette, m_transparentIndex, nullptr);
return palette;
}

View File

@ -38,7 +38,8 @@ Palette* create_palette_from_rgb(
frame_t fromFrame,
frame_t toFrame,
bool withAlpha,
Palette* palette)
Palette* palette,
PaletteOptimizerDelegate* delegate)
{
PaletteOptimizer optimizer;
@ -54,6 +55,14 @@ Palette* create_palette_from_rgb(
for (frame_t frame=fromFrame; frame<=toFrame; ++frame) {
render.renderSprite(flat_image.get(), sprite, frame);
optimizer.feedWithImage(flat_image.get(), withAlpha);
if (delegate) {
if (!delegate->onPaletteOptimizerContinue())
return nullptr;
delegate->onPaletteOptimizerProgress(
double(frame-fromFrame+1) / double(toFrame-fromFrame+1));
}
}
// Generate an optimized palette
@ -61,7 +70,8 @@ Palette* create_palette_from_rgb(
palette,
// Transparent color is needed if we have transparent layers
(sprite->backgroundLayer() &&
sprite->countLayers() == 1 ? -1: sprite->transparentColor()));
sprite->countLayers() == 1 ? -1: sprite->transparentColor()),
delegate);
return palette;
}
@ -366,7 +376,8 @@ void PaletteOptimizer::feedWithRgbaColor(color_t color)
m_histogram.addSamples(color, 1);
}
void PaletteOptimizer::calculate(Palette* palette, int maskIndex)
void PaletteOptimizer::calculate(Palette* palette, int maskIndex,
PaletteOptimizerDelegate* delegate)
{
// If the sprite has a background layer, the first entry can be
// used, in other case the 0 indexed will be the mask color, so it

View File

@ -26,11 +26,18 @@ namespace doc {
namespace render {
using namespace doc;
class PaletteOptimizerDelegate {
public:
virtual ~PaletteOptimizerDelegate() { }
virtual void onPaletteOptimizerProgress(double progress) = 0;
virtual bool onPaletteOptimizerContinue() = 0;
};
class PaletteOptimizer {
public:
void feedWithImage(Image* image, bool withAlpha);
void feedWithRgbaColor(color_t color);
void calculate(Palette* palette, int maskIndex);
void calculate(Palette* palette, int maskIndex, PaletteOptimizerDelegate* delegate);
private:
ColorHistogram<5, 6, 5, 5> m_histogram;
@ -42,7 +49,8 @@ namespace render {
frame_t fromFrame,
frame_t toFrame,
bool withAlpha,
Palette* newPalette); // Can be NULL to create a new palette
Palette* newPalette, // Can be NULL to create a new palette
PaletteOptimizerDelegate* delegate);
// Changes the image pixel format. The dithering method is used only
// when you want to convert from RGB to Indexed.