Skip to content

Commit

Permalink
Refine blur/dilate core algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
vinniefalco committed Dec 22, 2012
1 parent 2716f88 commit 703c060
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 132 deletions.
1 change: 1 addition & 0 deletions Extern/VFLib/Builds/VisualStudio2010/VFLib.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -874,6 +874,7 @@
<ClInclude Include="..\..\modules\vf_unfinished\graphics\vf_InnerGlowStyle.h" />
<ClInclude Include="..\..\modules\vf_unfinished\graphics\vf_InnerShadowStyle.h" />
<ClInclude Include="..\..\modules\vf_unfinished\graphics\vf_LayerGraphics.h" />
<ClInclude Include="..\..\modules\vf_unfinished\graphics\vf_LayerStyles.h" />
<ClInclude Include="..\..\modules\vf_unfinished\graphics\vf_LightingTransform.h" />
<ClInclude Include="..\..\modules\vf_unfinished\graphics\vf_OuterGlowStyle.h" />
<ClInclude Include="..\..\modules\vf_unfinished\graphics\vf_PatternFill.h" />
Expand Down
3 changes: 3 additions & 0 deletions Extern/VFLib/Builds/VisualStudio2010/VFLib.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -1004,6 +1004,9 @@
<ClInclude Include="..\..\modules\vf_unfinished\graphics\vf_BoxBlur.h">
<Filter>VF Modules\vf_unfinished\graphics</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\vf_unfinished\graphics\vf_LayerStyles.h">
<Filter>VF Modules\vf_unfinished\graphics</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\README.md" />
Expand Down
2 changes: 2 additions & 0 deletions Extern/VFLib/modules/vf_unfinished/graphics/vf_BoxBlur.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ struct BoxBlur
/** Single box blur pass.
This transposes rows and columns.
Original version by Brian Fiete
*/
struct Pass
{
Expand Down
17 changes: 11 additions & 6 deletions Extern/VFLib/modules/vf_unfinished/graphics/vf_DistanceTransform.h
Original file line number Diff line number Diff line change
Expand Up @@ -906,6 +906,10 @@ struct DistanceTransform

//----------------------------------------------------------------------------

/** Calculate Chamfer-5-7-11 distance transform.
Original version by Brian Fiete.
*/
struct Chamfer
{
/** Clamp v to the half-open interval [vmin, vmax)
Expand All @@ -921,8 +925,8 @@ struct DistanceTransform
return v;
}

template <class Functor, class BoolImage>
static void calculate (Functor f, BoolImage test, int const width, int const height)
template <class In, class Out>
void operator () (In in, Out out, int const width, int const height)
{
static int const kd [][2] = {
{-1, -2}, {1, -2},
Expand All @@ -949,10 +953,11 @@ struct DistanceTransform
{
for (int x = 0; x < width; ++x)
{
if (test (x, y))
d (x, y) = 0;
else
int const v = in (x, y);
if (v == 0)
d (x, y) = inf;
else
d (x, y) = 255 - v;
}
}

Expand Down Expand Up @@ -984,7 +989,7 @@ struct DistanceTransform
d (x, y) = v;
}

f (x, y, d (x, y));
out (x, y, d (x, y));
}
}
}
Expand Down
67 changes: 67 additions & 0 deletions Extern/VFLib/modules/vf_unfinished/graphics/vf_LayerStyles.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*============================================================================*/
/*
VFLib: https://github.com/vinniefalco/VFLib
Copyright (C) 2008 by Vinnie Falco <vinnie.falco@gmail.com>
This library contains portions of other open source products covered by
separate licenses. Please see the corresponding source files for specific
terms.
VFLib is provided under the terms of The MIT License (MIT):
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
*/
/*============================================================================*/

/** Common routines for Layer Styles.
*/
class LayerStyles
{
public:
/** Calculate blur and dilate settings.
*/
struct BoxBlurAndDilateSettings
{
BoxBlurAndDilateSettings (int sizeInPixels, float spread)
{
m_dilatePixels = int (sizeInPixels * spread + 0.5);

int blurPixels = sizeInPixels - m_dilatePixels;

// Photoshop fudge factor by Brian Fiete
float const fudge = 1.85f - 0.45f * std::min (1.0f, blurPixels / 10.f);
m_boxBlurRadius = std::max ((blurPixels - fudge) / 2.f, 0.f);
}

int getDilatePixels () const
{
return m_dilatePixels;
}

float getBoxBlurRadius () const
{
return m_boxBlurRadius;
}

private:
int m_dilatePixels;
float m_boxBlurRadius;
};
};
155 changes: 29 additions & 126 deletions Extern/VFLib/modules/vf_unfinished/graphics/vf_OuterGlowStyle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,110 +306,38 @@ struct OuterGlowStyle::RenderChamfer

/** Dilate 8-bit mask.
*/
struct OuterGlowStyle::GrayscaleDilation
struct OuterGlowStyle::ChamferDilation
{
struct EuclideanMetric
struct Output
{
template <class T>
static inline T f (T x_i, T gi) noexcept
Output (Map2D <int> dest, int size)
: m_dest (dest)
, m_size (size * 256)
, m_sizePlusOne (m_size + 256)
{
return (x_i*x_i)+gi*gi;
}

template <class T>
static inline T sep (T i, T u, T gi, T gu, T) noexcept
// distance is 8bit fixed point
void operator () (int x, int y, int distance)
{
return (u*u - i*i + gu*gu - gi*gi) / (2*(u-i));
if (distance <= m_size)
m_dest (x, y) = 255;
else if (distance < m_sizePlusOne)
m_dest (x, y) = 255 - (distance - m_size);
else
m_dest (x, y) = 0;
}

private:
Map2D <int> m_dest;
int m_size;
int m_sizePlusOne;
};

template <class In, class Out, class Metric>
void operator () (In in, Out out, int width, int height, int size, Metric metric) const
template <class In, class Out>
void operator () (In in, Out out, int width, int height, int size) const
{
int const sizeSquared = size * size;
int const sizePlusOneSquared = (size + 1) * (size + 1);

std::vector <int> g (width * height);

int const inf = width + height;

// phase 1
{
for (int x = 0; x < width; ++x)
{
g [x] = in (x, 0) > 128 ? 0 : inf;

// scan 1
for (int y = 1; y < height; ++y)
{
int const ym = y*width;
g [x+ym] = in (x, y) > 128 ? 0 : 1 + g [x+ym-width];
}

// scan 2
for (int y = height-2; y >=0; --y)
{
int const ym = y*width;

if (g [x+ym+width] < g [x+ym])
g [x+ym] = 1 + g[x+ym+width];
}
}
}

// phase 2
{
std::vector <int> s (jmax (width, height));
std::vector <int> t (jmax (width, height));

for (int y = 0; y < height; ++y)
{
int q = 0;
s [0] = 0;
t [0] = 0;

int const ym = y*width;

// scan 3
for (int u = 1; u < width; ++u)
{
while (q >= 0 && metric.f (t[q]-s[q], g[s[q]+ym]) > metric.f (t[q]-u, g[u+ym]))
q--;

if (q < 0)
{
q = 0;
s [0] = u;
}
else
{
int const w = 1 + metric.sep (s[q], u, g[s[q]+ym], g[u+ym], inf);

if (w < width)
{
++q;
s[q] = u;
t[q] = w;
}
}
}

// scan 4
for (int u = width-1; u >= 0; --u)
{
int const d = metric.f (u-s[q], g[s[q]+ym]);
if (d <= sizeSquared)
out (u, y) = 255;
else if (d < sizePlusOneSquared)
out (u, y) = 255*((size+1)-sqrt(double(d)));
else
//out (u, y) = sqrt(double(d));
out (u, y) = 0;
if (u == t[q])
--q;
}
}
}
DistanceTransform::Chamfer () (in, Output (out, size), width, height);
}
};

Expand Down Expand Up @@ -437,7 +365,7 @@ void OuterGlowStyle::operator() (Pixels destPixels, Pixels maskPixels)
maskPixels.getHeight (),
DistanceTransform::Meijster::EuclideanMetric ());
#else
DistanceTransform::Chamfer::calculate (
DistanceTransform::Chamfer () (
RenderPixel (
destPixels,
opacity,
Expand All @@ -446,9 +374,7 @@ void OuterGlowStyle::operator() (Pixels destPixels, Pixels maskPixels)
table),
DistanceTransform::BlackTest (maskPixels),
maskPixels.getWidth (),
maskPixels.getHeight ()
//,DistanceTransform::Meijster::ChessMetric ());
);
maskPixels.getHeight ());
#endif
}
else
Expand All @@ -457,41 +383,18 @@ void OuterGlowStyle::operator() (Pixels destPixels, Pixels maskPixels)

Map2D <int> temp (maskPixels.getWidth (), maskPixels.getHeight ());

#if 0
BoxBlur () (Pixels::Map2D (maskPixels), temp, temp.getCols (), temp.getRows (), size);
#else
int const dilatePixels = int (size * spread);
int const blurPixels = size - dilatePixels;
LayerStyles::BoxBlurAndDilateSettings bd (size, spread);

Map2D <int> dist (maskPixels.getWidth (), maskPixels.getHeight ());

GrayscaleDilation () (
ChamferDilation () (
Pixels::Map2D (maskPixels),
dist,
maskPixels.getWidth (),
maskPixels.getHeight (),
dilatePixels,
GrayscaleDilation::EuclideanMetric ());
/*
DistanceTransform::Meijster::calculateAntiAliased (
RenderChamfer (dist, dilatePixels),
GetMask (maskPixels),
maskPixels.getWidth (),
maskPixels.getHeight (),
DistanceTransform::Meijster::EuclideanMetric ());
*/
/*
for (int y = 0; y < temp.getRows (); ++y)
for (int x = 0; x < temp.getCols (); ++x)
dist (x, y) = (*maskPixels.getPixelPointer (x, y) > 0) ? 255 : 0;
*/
BoxBlur () (dist, temp, temp.getCols (), temp.getRows (), blurPixels);
/*
for (int y = 0; y < temp.getRows (); ++y)
for (int x = 0; x < temp.getCols (); ++x)
temp (x, y) = dist (x, y);
*/
#endif
bd.getDilatePixels ());

BoxBlur () (dist, temp, temp.getCols (), temp.getRows (), bd.getBoxBlurRadius ());

PixelARGB c (0);
for (int y = 0; y < temp.getRows (); ++y)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ struct OuterGlowStyle

struct RenderChamfer;
struct GrayscaleDilation;
struct ChamferDilation;

struct RenderPixel
{
Expand Down
1 change: 1 addition & 0 deletions Extern/VFLib/modules/vf_unfinished/vf_unfinished.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
namespace vf
{

#include "graphics/vf_LayerStyles.h"
#include "graphics/vf_BlendMode.h"
#include "graphics/vf_BlendProc.h"
#include "graphics/vf_BoxBlur.h"
Expand Down

0 comments on commit 703c060

Please sign in to comment.