From: jfbarraud Date: Sun, 24 Feb 2008 01:35:24 +0000 (+0000) Subject: pixblock-transform and scaler: convert src if needed, to match dest mode. X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=c6843f4373787d9ec7987e26edaaea04a0996cbf;p=inkscape.git 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... --- 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=0 && coordyarea.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=0 && coordyempty = 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 */