Optimized output picture saving
This commit is contained in:
parent
0abfa97295
commit
99aff57d6c
3 changed files with 54 additions and 34 deletions
|
@ -98,7 +98,19 @@ CanvasPortion *Canvas::atPixel(int x, int y) const
|
|||
int pwidth = portions[0]->getWidth();
|
||||
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
|
||||
|
|
|
@ -15,18 +15,14 @@ CanvasPictureWriter::CanvasPictureWriter(const Canvas *canvas):
|
|||
width = canvas->getWidth();
|
||||
height = canvas->getHeight();
|
||||
|
||||
last_portion = NULL;
|
||||
last_stream = NULL;
|
||||
last_y = 0;
|
||||
cache = new Color[1];
|
||||
cache_y = -antialias;
|
||||
cache_width = 0;
|
||||
}
|
||||
|
||||
CanvasPictureWriter::~CanvasPictureWriter()
|
||||
{
|
||||
delete profile;
|
||||
if (last_stream)
|
||||
{
|
||||
delete last_stream;
|
||||
}
|
||||
}
|
||||
|
||||
void CanvasPictureWriter::setAntialias(int antialias)
|
||||
|
@ -85,32 +81,44 @@ unsigned int CanvasPictureWriter::getPixel(int x, int y)
|
|||
|
||||
Color CanvasPictureWriter::getRawPixel(int x, int y)
|
||||
{
|
||||
// Get the portion this pixel is in
|
||||
CanvasPortion *portion = canvas->atPixel(x, y);
|
||||
if (not (y >= cache_y && y < cache_y + antialias))
|
||||
{
|
||||
// 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
|
||||
if (portion != last_portion or last_y != y)
|
||||
CanvasPortion *portion = NULL;
|
||||
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
|
||||
if (last_stream)
|
||||
for (int cx = 0; cx < cache_width; cx++)
|
||||
{
|
||||
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 (portion->getReadStream(*last_stream, x - portion->getXOffset(), y - portion->getYOffset()))
|
||||
if (has_pixels)
|
||||
{
|
||||
last_portion = portion;
|
||||
last_y = y;
|
||||
itcolor->load(stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Portion has no stream
|
||||
return COLOR_BLACK;
|
||||
*itcolor = COLOR_BLACK;
|
||||
}
|
||||
itcolor++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load the pixel
|
||||
Color col;
|
||||
col.load(last_stream);
|
||||
return col;
|
||||
// Hit the cache
|
||||
return cache[(y - cache_y) * cache_width + x];
|
||||
}
|
||||
|
|
|
@ -47,9 +47,9 @@ private:
|
|||
int height;
|
||||
ColorProfile *profile;
|
||||
|
||||
CanvasPortion *last_portion;
|
||||
int last_y;
|
||||
PackStream *last_stream;
|
||||
int cache_y;
|
||||
int cache_width;
|
||||
Color *cache;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue