Optimized output picture saving

This commit is contained in:
Michaël Lemaire 2014-08-21 22:23:04 +02:00
parent 0abfa97295
commit 99aff57d6c
3 changed files with 54 additions and 34 deletions

View file

@ -98,7 +98,19 @@ CanvasPortion *Canvas::atPixel(int x, int y) const
int pwidth = portions[0]->getWidth(); int pwidth = portions[0]->getWidth();
int pheight = portions[0]->getHeight(); int pheight = portions[0]->getHeight();
return at(x / pwidth, y / pheight); int px = x / pwidth;
int py = y / pheight;
if (px >= horizontal_portion_count)
{
px = horizontal_portion_count - 1;
}
if (py >= vertical_portion_count)
{
py = vertical_portion_count - 1;
}
return at(px, py);
} }
bool Canvas::saveToDisk(const std::string &filepath, const ColorProfile &profile, int antialias) const bool Canvas::saveToDisk(const std::string &filepath, const ColorProfile &profile, int antialias) const

View file

@ -15,18 +15,14 @@ CanvasPictureWriter::CanvasPictureWriter(const Canvas *canvas):
width = canvas->getWidth(); width = canvas->getWidth();
height = canvas->getHeight(); height = canvas->getHeight();
last_portion = NULL; cache = new Color[1];
last_stream = NULL; cache_y = -antialias;
last_y = 0; cache_width = 0;
} }
CanvasPictureWriter::~CanvasPictureWriter() CanvasPictureWriter::~CanvasPictureWriter()
{ {
delete profile; delete profile;
if (last_stream)
{
delete last_stream;
}
} }
void CanvasPictureWriter::setAntialias(int antialias) void CanvasPictureWriter::setAntialias(int antialias)
@ -85,32 +81,44 @@ unsigned int CanvasPictureWriter::getPixel(int x, int y)
Color CanvasPictureWriter::getRawPixel(int x, int y) Color CanvasPictureWriter::getRawPixel(int x, int y)
{ {
// Get the portion this pixel is in if (not (y >= cache_y && y < cache_y + antialias))
CanvasPortion *portion = canvas->atPixel(x, y); {
// Load rows into cache
delete [] cache;
cache_y = y;
cache_width = canvas->getWidth();
cache = new Color[cache_width * antialias];
// While we stay in the same portion line, read is sequential in the stream CanvasPortion *portion = NULL;
if (portion != last_portion or last_y != y) PackStream *stream = new PackStream;
Color* itcolor = cache;
bool has_pixels = false;
for (int cy = cache_y; cy < cache_y + antialias; cy++)
{ {
// Get the pack stream positioned at the pixel for (int cx = 0; cx < cache_width; cx++)
if (last_stream)
{ {
delete last_stream; CanvasPortion *nportion = canvas->atPixel(cx, cy);
if (nportion != portion)
{
portion = nportion;
delete stream;
stream = new PackStream;
has_pixels = portion->getReadStream(*stream, cx - portion->getXOffset(), cy - portion->getYOffset());
} }
last_stream = new PackStream; if (has_pixels)
if (portion->getReadStream(*last_stream, x - portion->getXOffset(), y - portion->getYOffset()))
{ {
last_portion = portion; itcolor->load(stream);
last_y = y;
} }
else else
{ {
// Portion has no stream *itcolor = COLOR_BLACK;
return COLOR_BLACK; }
itcolor++;
}
} }
} }
// Load the pixel // Hit the cache
Color col; return cache[(y - cache_y) * cache_width + x];
col.load(last_stream);
return col;
} }

View file

@ -47,9 +47,9 @@ private:
int height; int height;
ColorProfile *profile; ColorProfile *profile;
CanvasPortion *last_portion; int cache_y;
int last_y; int cache_width;
PackStream *last_stream; Color *cache;
}; };
} }