X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fdisplay%2Fnr-filter-component-transfer.cpp;h=87f87c95ab981b4c34ac920648ddb7b6eda2d99c;hb=5baec7f2ec5b05a6781f10a30890c65112eef76e;hp=f4749de825f25b9a05c91c3ad0190c070f8174a7;hpb=0bc9ee8f2303d4ce3c89ae35ba6cc70366bd2234;p=inkscape.git diff --git a/src/display/nr-filter-component-transfer.cpp b/src/display/nr-filter-component-transfer.cpp index f4749de82..87f87c95a 100644 --- a/src/display/nr-filter-component-transfer.cpp +++ b/src/display/nr-filter-component-transfer.cpp @@ -3,6 +3,7 @@ * * Authors: * Felipe Corrêa da Silva Sanches + * Jasper van de Gronde * * Copyright (C) 2007 authors * @@ -14,9 +15,11 @@ #include "display/nr-filter-utils.h" #include "libnr/nr-pixblock.h" #include "libnr/nr-blit.h" +#include "libnr/nr-pixops.h" #include -namespace NR { +namespace Inkscape { +namespace Filters { FilterComponentTransfer::FilterComponentTransfer() { @@ -42,13 +45,10 @@ int FilterComponentTransfer::render(FilterSlot &slot, FilterUnits const &/*units int y0=in->area.y0; int y1=in->area.y1; - NRPixBlock *out = new NRPixBlock; - nr_pixblock_setup_fast(out, NR_PIXBLOCK_MODE_R8G8B8A8N, x0, y0, x1, y1, true); - - // this primitive is defined for non-premultiplied RGBA values, + // this primitive is defined for RGBA values, // thus convert them to that format before blending bool free_in_on_exit = false; - if (in->mode != NR_PIXBLOCK_MODE_R8G8B8A8N) { + if (in->mode != NR_PIXBLOCK_MODE_R8G8B8A8N && in->mode != NR_PIXBLOCK_MODE_R8G8B8A8P) { NRPixBlock *original_in = in; in = new NRPixBlock; nr_pixblock_setup_fast(in, NR_PIXBLOCK_MODE_R8G8B8A8N, @@ -58,6 +58,10 @@ int FilterComponentTransfer::render(FilterSlot &slot, FilterUnits const &/*units nr_blit_pixblock_pixblock(in, original_in); free_in_on_exit = true; } + bool premultiplied = in->mode == NR_PIXBLOCK_MODE_R8G8B8A8P; + + NRPixBlock *out = new NRPixBlock; + nr_pixblock_setup_fast(out, in->mode, x0, y0, x1, y1, true); unsigned char *in_data = NR_PIXBLOCK_PX(in); unsigned char *out_data = NR_PIXBLOCK_PX(out); @@ -68,14 +72,14 @@ int FilterComponentTransfer::render(FilterSlot &slot, FilterUnits const &/*units int size = 4 * (y1-y0) * (x1-x0); int i; - for (int color=0;color<4;color++){ + int color=4; + while(color-->0) { int _vsize = tableValues[color].size(); - std::vector _tableValues = tableValues[color]; double _intercept = intercept[color]; double _slope = slope[color]; double _amplitude = amplitude[color]; double _exponent = exponent[color]; - double _offset = offset[color]; + double _offset = offset[color]; switch(type[color]){ case COMPONENTTRANSFER_TYPE_IDENTITY: for(i=color;i _tableValues(tableValues[color]); + // Scale by 255 and add .5 to avoid having to add it later for rounding purposes + // Note that this means that CLAMP_D_TO_U8 cannot be used here (as it includes rounding!) + for(i=0;i<_vsize;i++) { + _tableValues[i] = std::max(0.,std::min(255.,255*_tableValues[i])) + .5; + } + for(i=color;i((_vsize-1) * in_data[i]); + double dx = ((_vsize-1) * in_data[i])/255.0 - k; + out_data[i] = static_cast(_tableValues[k] + dx * (_tableValues[k+1] - _tableValues[k])); + } + } else { + std::vector _tableValues(tableValues[color]); + for(i=0;i<_vsize;i++) { + _tableValues[i] = std::max(0.,std::min(1.,_tableValues[i])); + } + for(i=color;i _tableValues(_vsize); + // Convert to unsigned char + for(i=0;i<_vsize;i++) { + _tableValues[i] = CLAMP_D_TO_U8(255*tableValues[color][i]); + } + for(i=color;i((_vsize-1) * in_data[i]); + out_data[i] = _tableValues[k]; + } + } else { + std::vector _tableValues(tableValues[color]); + for(i=0;i<_vsize;i++) { + _tableValues[i] = std::max(0.,std::min(1.,_tableValues[i])); + } + for(i=color;i