Page 1 of 1

ClampPixel vs ClampToQuantum

Posted: 2015-01-27T06:58:29-07:00
by argv[0]

Code: Select all

static inline Quantum ClampPixel(const MagickRealType value)
{
  if (value < 0.0f)
    return(0);
  if (value >= (MagickRealType) QuantumRange)
    return((Quantum) QuantumRange);
#if !defined(MAGICKCORE_HDRI_SUPPORT)
  return((Quantum) (value+0.5f));
#else
  return((Quantum) value);
#endif
}

Code: Select all

static inline Quantum ClampToQuantum(const MagickRealType value)
{
#if defined(MAGICKCORE_HDRI_SUPPORT)
  return((Quantum) value);
#else
  if (value <= 0.0f)
    return((Quantum) 0);
  if (value >= (MagickRealType) QuantumRange)
    return(QuantumRange);
  return((Quantum) (value+0.5f));
#endif
}
Part of "diff -ru ImageMagick-6.9.0-2/magick/composite.c ImageMagick-6.9.0-4/magick/composite.c" output:

Code: Select all

@@ -2850,14 +2847,14 @@
           composite.blue=(MagickRealType) QuantumRange-composite.blue;
           composite.index=(MagickRealType) QuantumRange-composite.index;
         }
-      SetPixelRed(q,ClampToQuantum(composite.red));
-      SetPixelGreen(q,ClampToQuantum(composite.green));
-      SetPixelBlue(q,ClampToQuantum(composite.blue));
-      SetPixelOpacity(q,ClampToQuantum(composite.opacity));
+      SetPixelRed(q,ClampPixel(composite.red));
+      SetPixelGreen(q,ClampPixel(composite.green));
+      SetPixelBlue(q,ClampPixel(composite.blue));
+      SetPixelOpacity(q,ClampPixel(composite.opacity));
       if (image->colorspace == CMYKColorspace)
-        SetPixelIndex(indexes+x,ClampToQuantum(composite.index));
+        SetPixelIndex(indexes+x,ClampPixel(composite.index));
       p++;
-      if (p >= (pixels+composite_image->columns))
+      if (p >= (pixels+source_image->columns))
         p=pixels;
       q++;
     }
As a result in ImageMagick-6.9.0-4 any composite operation on floating-point TIFF clamps all channels to 1.0.
Composite operations in ImageMagick-6.9.0-2 doesn't clamp floating-point image.

Re: ClampPixel vs ClampToQuantum

Posted: 2015-01-27T07:14:13-07:00
by magick
We're following the SVG compositing specification. The conundrum is "should" rather than "must" in this statement:
In addition to the base set of 12 Porter-Duff operations, a number of blending operations are supported. These blending operations are extensions of the base Porter-Duff set and provide enhanced compositing behavior. The extended operations may result in color and opacity values outside the range zero to one. The opacity value should be clamped between zero and one inclusive, and the pre-multiplied color value should be clamped between zero and the opacity value inclusive.
@ http://www.w3.org/TR/2009/WD-SVGCompositing-20090430/. The question is "should" ImageMagick clamp the values or "must" it? Or do we set an option to support either behavior?

Re: ClampPixel vs ClampToQuantum

Posted: 2015-01-27T08:15:20-07:00
by argv[0]
Well. Standard is standard. But clamping makes HDRI processing difficult. May be worth to add "-define compose:clamping=(true|false)" (or something else) to control this behavior?

Re: ClampPixel vs ClampToQuantum

Posted: 2015-01-27T09:35:41-07:00
by magick
We could revert and enforce clamping with the -clamp option for HDRI. Let's do that. Will add a patch likely by tomorrow.

Re: ClampPixel vs ClampToQuantum

Posted: 2015-04-21T03:18:05-07:00
by argv[0]
ImageMagick-6.9.1-1 has the same problem.

Re: ClampPixel vs ClampToQuantum

Posted: 2015-04-21T04:19:37-07:00
by magick
The SVG compositing specification @ http://www.w3.org/TR/SVGCompositing/ says:
  • 3.1 Alpha Compositing Syntax

    This section in normative.

    When compositing using Porter-Duff extended blending operations color and opacity values may fall outside the range zero to one.

    A User Agent MUST clamp color and opacity values between zero and one inclusive.
    A User Agent MUST clamp premultiplied color values between zero and one inclusive.
Seems definitive, clamping is required. That will be the default behavior. However, we'll add an option as you suggested to prevent clamping.

Re: ClampPixel vs ClampToQuantum

Posted: 2015-04-21T09:31:27-07:00
by fmw42
Has this been added to 6.9.1.2 or is/will it be in 6.9.1.3 and is it in the IM 7 beta, yet? I have the same issue. There are times when clamping mathematical compose methods causes issues in my scripts.

Re: ClampPixel vs ClampToQuantum

Posted: 2015-04-21T11:15:24-07:00
by magick
Install ImageMagick-6.9.1-3 Beta, available now. Turn off clamping with -define compose:clamp=false or -set option:compose:clamp=false.

Re: ClampPixel vs ClampToQuantum

Posted: 2015-04-22T10:11:54-07:00
by argv[0]
It works (with a little patch). Thanks a lot!

Code: Select all

--- magick/composite.c.orig 2015-04-21 12:23:35.000000000 +0000
+++ magick/composite.c  2015-04-22 18:10:30.714484466 +0000
@@ -2860,9 +2860,9 @@
         ClampPixel(composite.red) : ClampToQuantum(composite.red));
       SetPixelGreen(q,clamp != MagickFalse ?
         ClampPixel(composite.green) : ClampToQuantum(composite.green));
-      SetPixelRed(q,clamp != MagickFalse ?
+      SetPixelBlue(q,clamp != MagickFalse ?
         ClampPixel(composite.blue) : ClampToQuantum(composite.blue));
-      SetPixelRed(q,clamp != MagickFalse ?
+      SetPixelOpacity(q,clamp != MagickFalse ?
         ClampPixel(composite.opacity) : ClampToQuantum(composite.opacity));
       if (image->colorspace == CMYKColorspace)
         SetPixelIndex(indexes+x,clamp != MagickFalse ?