aboutsummaryrefslogtreecommitdiff
path: root/dw
diff options
context:
space:
mode:
authorJorge Arellano Cid <jcid@dillo.org>2013-12-04 11:41:21 -0300
committerJorge Arellano Cid <jcid@dillo.org>2013-12-04 11:41:21 -0300
commit5856a620dd96e458b4018bd9d65e28cdbc9907cf (patch)
tree0db4ade7f4a71af788d28ae88ff8846bf61f8af9 /dw
parentcf10006850854433dbc777a478e7924239b90791 (diff)
Fix a couple of bugs in scaleRowBeautiful
An infinite loop situation (corner case race condition) and also avoid rescaling already scaled rows (speed).
Diffstat (limited to 'dw')
-rw-r--r--dw/fltkimgbuf.cc36
1 files changed, 19 insertions, 17 deletions
diff --git a/dw/fltkimgbuf.cc b/dw/fltkimgbuf.cc
index e526ad60..d9d653ec 100644
--- a/dw/fltkimgbuf.cc
+++ b/dw/fltkimgbuf.cc
@@ -143,7 +143,7 @@ void FltkImgbuf::init (Type type, int width, int height, double gamma,
scaledBuffers = new lout::container::typed::List <FltkImgbuf> (true);
else
scaledBuffers = NULL;
-
+
if (!isRoot()) {
// Scaling
for (int row = 0; row < root->height; row++) {
@@ -228,31 +228,33 @@ inline void FltkImgbuf::scaleRowBeautiful (int row, const core::byte *data)
{
int sr1 = scaledY (row);
int sr2 = scaledY (row + 1);
+ bool allRootRows = false;
- for (int sr = sr1; sr < sr2; sr++)
- copiedRows->set (sr, true);
+ // Don't rescale rows!
+ if (copiedRows->get(sr1)) return;
- if (height > root->height)
+ if (height > root->height) {
scaleBuffer (data, root->width, 1,
rawdata + sr1 * width * bpp, width, sr2 - sr1,
bpp, gamma);
- else {
- assert (sr1 ==sr2 || sr1 + 1 == sr2);
+ // Mark scaled rows done
+ for (int sr = sr1; sr < sr2 || sr == sr1; sr++)
+ copiedRows->set (sr, true);
+ } else {
+ assert (sr1 == sr2 || sr1 + 1 == sr2);
int row1 = backscaledY(sr1), row2 = backscaledY(sr1 + 1);
- // Draw only when all original lines are retrieved (speed).
- bool allRootRows = true;
- for (int r = row1; allRootRows && r < row2; r++)
- allRootRows = allRootRows && root->copiedRows->get(r);
-
- if (allRootRows)
- // We have to access root->rawdata (which has to be up to
- // date), since a larger area than the single row is accessed
- // here.
+ // Check all the necessary root lines already arrived,
+ // a larger area than a single row may be accessed here.
+ for (int r=row1; (allRootRows=root->copiedRows->get(r)) && ++r < row2; );
+ if (allRootRows) {
scaleBuffer (root->rawdata + row1 * root->width * bpp,
root->width, row2 - row1,
rawdata + sr1 * width * bpp, width, 1,
bpp, gamma);
+ // Mark scaled row done
+ copiedRows->set (sr1, true);
+ }
}
}
@@ -295,7 +297,7 @@ inline void FltkImgbuf::scaleBuffer (const core::byte *src, int srcWidth,
int yo1 = y * srcHeight / destHeight;
int yo2 = lout::misc::max ((y + 1) * srcHeight / destHeight, yo1 + 1);
int n = (xo2 - xo1) * (yo2 - yo1);
-
+
int v[bpp];
for(int i = 0; i < bpp; i++)
v[i] = 0;
@@ -328,7 +330,7 @@ void FltkImgbuf::copyRow (int row, const core::byte *data)
for (Iterator <FltkImgbuf> it = scaledBuffers->iterator();
it.hasNext(); ) {
FltkImgbuf *sb = it.getNext ();
- sb->scaleRow(row, data);
+ sb->scaleRow (row, data);
}
}
}