summaryrefslogtreecommitdiffstats
path: root/src/display
diff options
context:
space:
mode:
authorJF Barraud <jf.barraud@gmail.com>2008-02-24 01:35:24 +0000
committerjfbarraud <jfbarraud@users.sourceforge.net>2008-02-24 01:35:24 +0000
commite0313f357f9cb36a493497a637866bec35f28752 (patch)
tree384405cab5da7a77143b4e5e890a9dc8e45e3b08 /src/display
parentWarning and whitespace cleanup (diff)
downloadinkscape-e0313f357f9cb36a493497a637866bec35f28752.tar.gz
inkscape-e0313f357f9cb36a493497a637866bec35f28752.zip
pixblock-transform and scaler: convert src if needed, to match dest mode.
color matrix, comp. transfert and diplacement map: explicitely free some unused pixblock instead of resting on garbage collection... (bzr r4839)
Diffstat (limited to 'src/display')
-rw-r--r--src/display/nr-filter-colormatrix.cpp8
-rw-r--r--src/display/nr-filter-component-transfer.cpp7
-rw-r--r--src/display/nr-filter-displacement-map.cpp85
-rw-r--r--src/display/pixblock-scaler.cpp7
-rw-r--r--src/display/pixblock-transform.cpp19
5 files changed, 84 insertions, 42 deletions
diff --git a/src/display/nr-filter-colormatrix.cpp b/src/display/nr-filter-colormatrix.cpp
index 054b3899b..79c6177ab 100644
--- a/src/display/nr-filter-colormatrix.cpp
+++ b/src/display/nr-filter-colormatrix.cpp
@@ -43,6 +43,7 @@ int FilterColorMatrix::render(FilterSlot &slot, FilterUnits const &/*units*/) {
// this primitive is defined for non-premultiplied RGBA values,
// thus convert them to that format
+ bool free_in_on_exit = false;
if (in->mode != NR_PIXBLOCK_MODE_R8G8B8A8N) {
NRPixBlock *original_in = in;
in = new NRPixBlock;
@@ -51,6 +52,7 @@ int FilterColorMatrix::render(FilterSlot &slot, FilterUnits const &/*units*/) {
original_in->area.x1, original_in->area.y1,
false);
nr_blit_pixblock_pixblock(in, original_in);
+ free_in_on_exit = true;
}
unsigned char *in_data = NR_PIXBLOCK_PX(in);
@@ -143,6 +145,12 @@ int FilterColorMatrix::render(FilterSlot &slot, FilterUnits const &/*units*/) {
case COLORMATRIX_ENDTYPE:
break;
}
+
+ if (free_in_on_exit) {
+ nr_pixblock_release(in);
+ delete in;
+ }
+
out->empty = FALSE;
slot.set(_output, out);
return 0;
diff --git a/src/display/nr-filter-component-transfer.cpp b/src/display/nr-filter-component-transfer.cpp
index 1edb3ac98..a81d8f53a 100644
--- a/src/display/nr-filter-component-transfer.cpp
+++ b/src/display/nr-filter-component-transfer.cpp
@@ -47,6 +47,7 @@ int FilterComponentTransfer::render(FilterSlot &slot, FilterUnits const &/*units
// this primitive is defined for non-premultiplied RGBA values,
// thus convert them to that format before blending
+ bool free_in_on_exit = false;
if (in->mode != NR_PIXBLOCK_MODE_R8G8B8A8N) {
NRPixBlock *original_in = in;
in = new NRPixBlock;
@@ -55,6 +56,7 @@ int FilterComponentTransfer::render(FilterSlot &slot, FilterUnits const &/*units
original_in->area.x1, original_in->area.y1,
false);
nr_blit_pixblock_pixblock(in, original_in);
+ free_in_on_exit = true;
}
unsigned char *in_data = NR_PIXBLOCK_PX(in);
@@ -117,6 +119,11 @@ int FilterComponentTransfer::render(FilterSlot &slot, FilterUnits const &/*units
}
}
+ if (free_in_on_exit) {
+ nr_pixblock_release(in);
+ delete in;
+ }
+
out->empty = FALSE;
slot.set(_output, out);
return 0;
diff --git a/src/display/nr-filter-displacement-map.cpp b/src/display/nr-filter-displacement-map.cpp
index 1345924fc..ecf0e8def 100644
--- a/src/display/nr-filter-displacement-map.cpp
+++ b/src/display/nr-filter-displacement-map.cpp
@@ -41,18 +41,11 @@ int FilterDisplacementMap::render(FilterSlot &slot, FilterUnits const &units) {
if (map->area.x1 <= map->area.x0 || map->area.y1 <= map->area.y0) return 0; //nothing to do!
NRPixBlock *out = new NRPixBlock;
-
- //are these checks really necessary?
- if (out_w > map->area.x1 - out_x0) out_w = map->area.x1 - out_x0;
- if (out_h > map->area.y1 - out_y0) out_h = map->area.y1 - out_y0;
- if (out_x0 < map->area.x0){
- out_x0 = map->area.x0;
- out_w -= (map->area.x0 - out_x0);
- }
- if (out_y0 < map->area.y0){
- out_y0 = map->area.y0;
- out_h -= (map->area.y0 - out_y0);
- }
+
+ out_x0 = map->area.x0;
+ out_y0 = map->area.y0;
+ out_w = map->area.x1 - map->area.x0;
+ out_h = map->area.y1 - map->area.y0;
out->area.x0 = out_x0;
out->area.y0 = out_y0;
@@ -63,6 +56,7 @@ int FilterDisplacementMap::render(FilterSlot &slot, FilterUnits const &units) {
// this primitive is defined for non-premultiplied RGBA values,
// thus convert them to that format
+ bool free_map_on_exit = false;
if (map->mode != NR_PIXBLOCK_MODE_R8G8B8A8N) {
NRPixBlock *original_map = map;
map = new NRPixBlock;
@@ -71,6 +65,7 @@ int FilterDisplacementMap::render(FilterSlot &slot, FilterUnits const &units) {
original_map->area.x1, original_map->area.y1,
false);
nr_blit_pixblock_pixblock(map, original_map);
+ free_map_on_exit = true;
}
unsigned char *map_data = NR_PIXBLOCK_PX(map);
@@ -87,29 +82,36 @@ int FilterDisplacementMap::render(FilterSlot &slot, FilterUnits const &units) {
for (x=0; x < out_w; x++){
for (y=0; y < out_h; y++){
- if (x+out_x0-map->area.x0 >= 0 &&
- x+out_x0-map->area.x0 < in_w &&
- y+out_y0-map->area.y0 >= 0 &&
- y+out_y0-map->area.y0 < in_h){
-
- coordx = out_x0 - map->area.x0 + x + scalex * ( double(map_data[4*((x+out_x0-map->area.x0) + in_w*(y+out_y0-map->area.y0)) + Xchannel])/255 - 0.5);
- coordy = out_y0 - map->area.y0 + y + scaley * ( double(map_data[4*((x+out_x0-map->area.x0) + in_w*(y+out_y0-map->area.y0)) + Ychannel])/255 - 0.5);
-
- if (coordx>=0 && coordx<in_w && coordy>=0 && coordy<in_h){
- out_data[4*(x + out_w*y)] = texture_data[4*(int(coordx) + int(coordy)*in_w)];
- out_data[4*(x + out_w*y) + 1] = texture_data[4*(int(coordx) + int(coordy)*in_w) + 1];
- out_data[4*(x + out_w*y) + 2] = texture_data[4*(int(coordx) + int(coordy)*in_w) + 2];
- out_data[4*(x + out_w*y) + 3] = texture_data[4*(int(coordx) + int(coordy)*in_w) + 3];
- } else {
- out_data[4*(x + out_w*y)] = 255;
- out_data[4*(x + out_w*y) + 1] = 255;
- out_data[4*(x + out_w*y) + 2] = 255;
- out_data[4*(x + out_w*y) + 3] = 0;
- }
+ int xmap = x+out_x0-map->area.x0;
+ int ymap = y+out_y0-map->area.y0;
+ if (xmap >= 0 &&
+ xmap < in_w &&
+ ymap >= 0 &&
+ ymap < in_h){
+
+ coordx = xmap + scalex * ( double(map_data[4*(xmap + in_w*ymap) + Xchannel]-128.)/256);
+ coordy = ymap + scaley * ( double(map_data[4*(xmap + in_w*ymap) + Ychannel]-128.)/256);
+
+ if (coordx>=0 && coordx<in_w && coordy>=0 && coordy<in_h){
+ out_data[4*(x + out_w*y) ] = texture_data[4*(int(coordx) + int(coordy)*in_w) ];
+ out_data[4*(x + out_w*y) + 1] = texture_data[4*(int(coordx) + int(coordy)*in_w) + 1];
+ out_data[4*(x + out_w*y) + 2] = texture_data[4*(int(coordx) + int(coordy)*in_w) + 2];
+ out_data[4*(x + out_w*y) + 3] = texture_data[4*(int(coordx) + int(coordy)*in_w) + 3];
+ } else {
+ out_data[4*(x + out_w*y) ] = 255;
+ out_data[4*(x + out_w*y) + 1] = 255;
+ out_data[4*(x + out_w*y) + 2] = 255;
+ out_data[4*(x + out_w*y) + 3] = 0;
+ }
}
}
}
+ if (free_map_on_exit) {
+ nr_pixblock_release(map);
+ delete map;
+ }
+
out->empty = FALSE;
slot.set(_output, out);
return 0;
@@ -140,18 +142,17 @@ void FilterDisplacementMap::set_channel_selector(int s, FilterDisplacementMapCha
void FilterDisplacementMap::area_enlarge(NRRectL &area, Matrix const &trans)
{
- out_x0 = area.x0;
- out_y0 = area.y0;
- out_w = area.x1 - area.x0;
- out_h = area.y1 - area.y0;
+ //I assume scale is in user coordinates (?!?)
+ //FIXME: trans should be multiplied by some primitiveunits2user, shouldn't it?
- double scalex = scale*trans.expansionX();
- double scaley = scale*trans.expansionY();
-
- area.x0 -= (int)(scalex/2);
- area.x1 += (int)(scalex/2);
- area.y0 -= (int)(scaley/2);
- area.y1 += (int)(scaley/2);
+ double scalex = scale/2.*(std::fabs(trans[0])+std::fabs(trans[1]));
+ double scaley = scale/2.*(std::fabs(trans[2])+std::fabs(trans[3]));
+
+ //FIXME: no +2 should be there!... (noticable only for big scales at big zoom factor)
+ area.x0 -= (int)(scalex)+2;
+ area.x1 += (int)(scalex)+2;
+ area.y0 -= (int)(scaley)+2;
+ area.y1 += (int)(scaley)+2;
}
FilterTraits FilterDisplacementMap::get_input_traits() {
diff --git a/src/display/pixblock-scaler.cpp b/src/display/pixblock-scaler.cpp
index 5bf3c2762..39c82daf6 100644
--- a/src/display/pixblock-scaler.cpp
+++ b/src/display/pixblock-scaler.cpp
@@ -96,11 +96,13 @@ static void scale_bicubic_rgba(NRPixBlock *to, NRPixBlock *from)
return;
}
+ bool free_from_on_exit = false;
if (from->mode != to->mode){
NRPixBlock *o_from = from;
from = new NRPixBlock;
nr_pixblock_setup_fast(from, to->mode, o_from->area.x0, o_from->area.y0, o_from->area.x1, o_from->area.y1, false);
nr_blit_pixblock_pixblock(from, o_from);
+ free_from_on_exit = true;
}
// Precalculate sizes of source and destination pixblocks
@@ -198,6 +200,11 @@ static void scale_bicubic_rgba(NRPixBlock *to, NRPixBlock *from)
}
}
}
+ if (free_from_on_exit) {
+ nr_pixblock_release(from);
+ delete from;
+ }
+
}
void scale_bicubic_alpha(NRPixBlock *to, NRPixBlock *from)
diff --git a/src/display/pixblock-transform.cpp b/src/display/pixblock-transform.cpp
index abe0f90c0..730f0ad43 100644
--- a/src/display/pixblock-transform.cpp
+++ b/src/display/pixblock-transform.cpp
@@ -52,6 +52,15 @@ void transform_nearest(NRPixBlock *to, NRPixBlock *from, Matrix &trans)
return;
}
+ bool free_from_on_exit = false;
+ if (from->mode != to->mode){
+ NRPixBlock *o_from = from;
+ from = new NRPixBlock;
+ nr_pixblock_setup_fast(from, to->mode, o_from->area.x0, o_from->area.y0, o_from->area.x1, o_from->area.y1, false);
+ nr_blit_pixblock_pixblock(from, o_from);
+ free_from_on_exit = true;
+ }
+
// Precalculate sizes of source and destination pixblocks
int from_width = from->area.x1 - from->area.x0;
int from_height = from->area.y1 - from->area.y0;
@@ -90,6 +99,10 @@ void transform_nearest(NRPixBlock *to, NRPixBlock *from, Matrix &trans)
NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x * 4 + 3] = result.a;
}
}
+ if (free_from_on_exit) {
+ nr_pixblock_release(from);
+ delete from;
+ }
}
/** Calculates cubically interpolated value of the four given pixel values.
@@ -149,11 +162,13 @@ void transform_bicubic(NRPixBlock *to, NRPixBlock *from, Matrix &trans)
return;
}
+ bool free_from_on_exit = false;
if (from->mode != to->mode){
NRPixBlock *o_from = from;
from = new NRPixBlock;
nr_pixblock_setup_fast(from, to->mode, o_from->area.x0, o_from->area.y0, o_from->area.x1, o_from->area.y1, false);
nr_blit_pixblock_pixblock(from, o_from);
+ free_from_on_exit = true;
}
// Precalculate sizes of source and destination pixblocks
@@ -255,6 +270,10 @@ void transform_bicubic(NRPixBlock *to, NRPixBlock *from, Matrix &trans)
}
}
}
+ if (free_from_on_exit) {
+ nr_pixblock_release(from);
+ delete from;
+ }
}
} /* namespace NR */