After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 166132 - Better image scaling algorithms, redux
Better image scaling algorithms, redux
Status: RESOLVED INVALID
Product: GIMP
Classification: Other
Component: General
unspecified
Other All
: Normal enhancement
: ---
Assigned To: GIMP Bugs
GIMP Bugs
Depends on:
Blocks:
 
 
Reported: 2005-02-03 05:51 UTC by Neil Toronto
Modified: 2005-02-03 16:07 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Neil Toronto 2005-02-03 05:51:59 UTC
A follow-up from bug #162250: Feature Request: Better image scaling algorithms.
Sven suggested a new bug report ("Having too many comments in a single bug
report makes it unlikely that it will be picked up anytime later.")

(Un-disclaimer: I do machine learning and image processing research at BYU.)

First, from an algorithmic standpoint (UI excluded), it would be VERY easy to
add a few new interpolants. This paper goes over a bunch with symmetrical,
separable kernels:

http://www.cvgpr.uni-mannheim.de/hornegger/MEDBV/handouts/lehmann.pdf

Page 1052 describes the algorithm template they're used in. One other nifty
resource I found was this:

http://www.ldv.ei.tum.de/media/files/dvi/vorlesung/z03_reconstruction_filters.pdf

page 223. From it, I wrote some code for one of my own projects:


/*
1/6 *

if |x| < 1, (12 - 9*B - 6*C)|x|^3 + (-18 + 12*B + 6*C)|x|^2 + (6 - 2*B)
else if |x| < 2, (-B - 6C)|x|^3 + (6*B + 30*C)|x|^2 + (-12*B - 48*C)|x| + (8*B +
24*C)
else 0

(B, C) =

(1, 0): cubic B-spline
(0, C): one-parameter family of cardinal cubics with (0, 0.5) being Catmull-Rom
(B, 0): Duff's tensioned B-splines
*/
static inline float cubicKernel(float x, float b, float c)
{
   float weight;
   float ax = (float)fabs(x);

   if (ax > 2) return 0;

   float x3 = ax * ax * ax;
   float x2 = ax * ax;

   if (ax < 1)
       weight = (12 - 9 * b - 6 * c) * x3 + (-18 + 12 * b + 6 * c) * x2 + (6 - 2
* b);
   else
       weight = (-b - 6 * c) * x3 + (6 * b + 30 * c) * x2 + (-12 * b - 48 * c) *
ax + (8 * b + 24 * c);

   return weight * (1.0f / 6.0f);
}

static inline float bicubicDistWeight(float dy, float dx, float b, float c)
{
   return cubicKernel(dy, b, c) * cubicKernel(dx, b, c);
}

static inline float bsplineDistWeight(float dy, float dx)
{
   return cubicKernel(dy, 1, 0) * cubicKernel(dx, 1, 0);
}

static inline float catmullRomDistWeight(float dy, float dx)
{
   return cubicKernel(dy, 0, 0.5f) * cubicKernel(dx, 0, 0.5f);
}


So if (B,C) = (0,0.5), you've got a Catmull-Rom kernel, which is what GIMP uses
right now in scale-funcs.c. If (B,C) = (1,0), it's a B-spline kernel, which
results in much a smoother (C-2 continuous) result, which GIMP could
*definitely* use.

Even better: if the bicubic interpolator were coded to smoothly transition
between (0,0.5) and (1,0), GIMP could give the users a sliding scale between
"smooth" and "sharp" bicubic interpolation. Photoshop's "Bicubic Smooth" and
"Bicubic Sharp" options have nothing on that.

General-interest FYI: Albert Cahalan's baby, Lanczos, may be the most "correct"
interpolant under a certain set of assumptions. Realize, however, that you can
always invent a set of assumptions (along with a set of fitness tests) that
makes one interpolant more "correct" than another. In fact, you can *prove* that
it's *impossible* to make a perfect generalization about between values from a
finite set of samples - a result from machine learning that generally gets
overlooked by the image processing community.
Comment 1 Neil Toronto 2005-02-03 05:53:09 UTC

*** This bug has been marked as a duplicate of 166130 ***
Comment 2 Raphaël Quinet 2005-02-03 16:07:05 UTC
Note to Neil Toronto: in this case (same bug accidentally reported twice by the
same person), it is better to mark the additional copy as INVALID instead of
DUPLICATE.  This avoids inflating the reports on most frequently reported bugs:
  http://bugzilla.gnome.org/reports/product-mostfrequent.cgi?product=GIMP

See also the GIMP developers FAQ:
  http://developer.gimp.org/faq.html#id2789416