From 99aff57d6cd626263f84bd7284299ada82d5b964 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Thu, 21 Aug 2014 22:23:04 +0200 Subject: [PATCH] Optimized output picture saving --- src/render/software/Canvas.cpp | 14 ++++- src/render/software/CanvasPictureWriter.cpp | 68 ++++++++++++--------- src/render/software/CanvasPictureWriter.h | 6 +- 3 files changed, 54 insertions(+), 34 deletions(-) diff --git a/src/render/software/Canvas.cpp b/src/render/software/Canvas.cpp index 8c9d0df..58726b0 100644 --- a/src/render/software/Canvas.cpp +++ b/src/render/software/Canvas.cpp @@ -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 diff --git a/src/render/software/CanvasPictureWriter.cpp b/src/render/software/CanvasPictureWriter.cpp index 22d1775..1354690 100644 --- a/src/render/software/CanvasPictureWriter.cpp +++ b/src/render/software/CanvasPictureWriter.cpp @@ -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); - - // While we stay in the same portion line, read is sequential in the stream - if (portion != last_portion or last_y != y) + if (not (y >= cache_y && y < cache_y + antialias)) { - // Get the pack stream positioned at the pixel - if (last_stream) + // Load rows into cache + delete [] cache; + cache_y = y; + cache_width = canvas->getWidth(); + cache = new Color[cache_width * antialias]; + + CanvasPortion *portion = NULL; + PackStream *stream = new PackStream; + + Color* itcolor = cache; + bool has_pixels = false; + for (int cy = cache_y; cy < cache_y + antialias; cy++) { - delete last_stream; - } - last_stream = new PackStream; - if (portion->getReadStream(*last_stream, x - portion->getXOffset(), y - portion->getYOffset())) - { - last_portion = portion; - last_y = y; - } - else - { - // Portion has no stream - return COLOR_BLACK; + for (int cx = 0; cx < cache_width; cx++) + { + 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()); + } + if (has_pixels) + { + itcolor->load(stream); + } + else + { + *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]; } diff --git a/src/render/software/CanvasPictureWriter.h b/src/render/software/CanvasPictureWriter.h index a07d3df..c0394cf 100644 --- a/src/render/software/CanvasPictureWriter.h +++ b/src/render/software/CanvasPictureWriter.h @@ -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; }; }