Page 1 of 1

Mixed percentage & numeric color coordinates

Posted: 2014-08-11T17:37:24-07:00
by tdhsmith
Perhaps this is a WONTFIX, but I couldn't easily find mention of it in the forums.

Could the IM color commands take inputs that are mixed among percentage and non-percentage values? I ask because of two issues:
  1. Including a percentage sign anywhere in the color forces the parser to assume all values are percentages without informing the user. So the user thinks they are getting rgb(240,15,50%), but really they are getting rgb(240%,15%,50%).
  2. Most definitions of the HSL and HSV color spaces specifically require coordinate asymmetry. The original paper* identifies that "hue is a circular or modular quality, while all the other characteristics mentioned imply the existence of minimum and maximum values" (and hence might be interpreted as scales or percentages). They ultimately place the saturation and lightness components on a scale from 0 to 1 and hue as an angle, but note that the "scaling ... is somewhat arbitrary".

    While IM implements an asymmetric numeric format (hue/360, sat/256, light/256), due to #1, entering any of the coordinates as a percentage will shift the entire format to a symmetrical one (hue/100%, sat/100%, light/100%). Thus a naive user following a traditional HSL specification might get unexpected colors, because it would be natural to enter S&L or S&V as percentages of their maximum value, but leave hue as a degree (or radian) value, since it does not have a clear "maximum".

    The CSS3 specification (http://dev.w3.org/csswg/css-color/#the-hsl-notation) is particularly troublesome because it only accepts the format the format "hsl(<hue>,<percentage>,<percentage>)". I don't know for certain, but I suspect CSS is one of the primary ways people are exposed to HSL.
I am also requesting this on behalf of the Sublime Text plugin GutterColor (https://github.com/ggordan/GutterColor), which utilizes IM to generate color samples. We could pretty easily convert the numbers on our end, but we thought it made more semantic sense for IM to handle it, so figured we might as well ask. :) Thanks!


Re: Mixed percentage & numeric color coordinates

Posted: 2014-08-11T17:42:52-07:00
by tdhsmith
FYI: I am willing to slowly plunk together a patch, but I have zero production C experience, and the ParseGeometry method seems to be pretty important (and full of historical design choices), so I wanted to just ask about the issue first, and see if it was on any roadmap. Cheers!

Re: Mixed percentage & numeric color coordinates

Posted: 2014-08-11T17:53:07-07:00
by fmw42
As far as I know, this is currently the way IM works. You have a choice of either 0-360 for hue and 0-255 for sat and lightness/brightness/intensity. Or all 3 are in the range of 0 to 100%. Think of the latter as range 0 to 1 for all 3 but multiplied by 100.

You cannot mix and match. One exception is alpha is always specified in HSL or RGB in the range 0 to 1. The other exceptions is that icc-color is always only specified in the range 0 to 1.

In most of IM functions, you have a choice of 0 to quantumrange for each channel or 0 to 100%. You cannot mix and match them either.

The IM developer would have to comment further about your issue and any changes for color values. I would suspect that this percent parsing goes deep in the guts of IM and may not be easily changed.

Discussion of color syntax is at http://www.imagemagick.org/script/color.php

Re: Mixed percentage & numeric color coordinates

Posted: 2014-08-11T20:45:40-07:00
by tdhsmith
fmw42 wrote:As far as I know, this is currently the way IM works. You have a choice of either 0-360 for hue and 0-255 for sat and lightness/brightness/intensity. Or all 3 are in the range of 0 to 100%. Think of the latter as range 0 to 1 for all 3 but multiplied by 100.
Yeah I can confirm this from my tests and the color syntax page you linked.
fmw42 wrote:I would suspect that this percent parsing goes deep in the guts of IM and may not be easily changed.
I've had a glance around the source, and it seems you are right, but I'm hoping maybe someone had been itching to change it anyway. :P

Specifically color.c utilizes geometry.c's ParseGeometry method. This method starts by running through the characters of the command string, settings flags to positive as it encounters characters. When it encounters a percent sign, the PercentValue flag is set.

Code: Select all

flags=NoValue;
[...]
for (p=pedantic_geometry; *p != '\0'; )
  {
    [...]
    switch (c)
    {
      case '%':
      {
        flags|=PercentValue;
        (void) CopyMagickString(p,p+1,MaxTextExtent);
        break;
      }
[...]
    }
  }
Then later color.c uses the PercentValue flag to scale the coordinates down to the range 0-1:

Code: Select all

          if ((LocaleCompare(colorspace,"HCL") == 0) ||
              (LocaleCompare(colorspace,"HSB") == 0) ||
              (LocaleCompare(colorspace,"HSL") == 0) ||
              (LocaleCompare(colorspace,"HWB") == 0))
            {
              PixelPacket
                pixel;

              scale=1.0/360.0;
              if ((flags & PercentValue) != 0)
                scale=1.0/100.0;
              geometry_info.rho*=360.0*scale;
              scale=1.0/255.0;
              if ((flags & PercentValue) != 0)
                scale=1.0/100.0;
              geometry_info.sigma*=scale;
              geometry_info.xi*=scale;
              [...]
            }
Maybe it isn't particularly C-like, but I was thinking of adding something like RhoPercentValue, SigmaPercentValue, and XiPercentValue flags. Then modify the comma-detection case of the string scan to add a comma counter variable that increments for each comma. Finally add conditionals on the percent sign case that set these new flags based on whether 0, 1, or 2 commas were found so far. Then color.c can check these coordinate-specific flags instead of the "full string" flag?

Re: Mixed percentage & numeric color coordinates

Posted: 2014-08-11T21:28:55-07:00
by fmw42
I have moved this topic from Bugs to Developers forum, since it is mostly a request for an enhancement rather than a bug.

Re: Mixed percentage & numeric color coordinates

Posted: 2014-08-11T21:50:48-07:00
by snibgo
IM parsing is generally quite primitive, with errors not caught. For example:

Code: Select all

F:\web\im>%IM%identify -format "%[fx:2+/3]" xc:
2
The ideal solution would be to re-write the parsing code. Ideally, this wouldn't break existing scripts that rely on current parsing oddities (eg a single "%" makes all numbers percents). This ideal isn't possible unless the old code remains, with some switch that specified whether to use old or new syntax.

Re: Mixed percentage & numeric color coordinates

Posted: 2015-08-01T14:47:17-07:00
by zweibieren
THIS IS NOT an enhancement request. Imagemagick got broken at some point. My old script used hsl(degree, number, number). It worked fine. When I try to use it now, IT FAILS. See the documentation http://www.imagemagick.org/MagickStudio/Color.html.

By now many people have written recent scripts using the new definition and parser. There is [alas] no way to make us all happy.

Here's a thought: when function definitions change, change the function name.

Re: Mixed percentage & numeric color coordinates

Posted: 2015-08-01T15:30:51-07:00
by fmw42
zweibieren wrote:THIS IS NOT an enhancement request. Imagemagick got broken at some point. My old script used hsl(degree, number, number). It worked fine. When I try to use it now, IT FAILS. See the documentation http://www.imagemagick.org/MagickStudio/Color.html.
This was intentionally changed a long time ago, since mixed notation did not seem to be reasonable or consistent. The current documentation at http://www.imagemagick.org/script/color.php, says:

"Prior to ImageMagick 6.5.6-6, HSL (HSB) could only be specified with Hue in range 0—360, but Saturation and Lightness (Brightness) as percent in range 0—100%."

In the changelog at http://www.imagemagick.org/script/changelog.php, it shows:

2009-09-25 6.5.6-6 Cristy <quetzlzacatenango@image...>
Permit percentage of hue for HSL (e.g. hsl(12%,...)).

2009-09-25 6.5.6-5 Cristy <quetzlzacatenango@image...>
Permit non-percentage HSL colors (e.g. hsl(12.6316,134.58339,219.00012)).

2009-09-22 6.5.6-4 Cristy <quetzlzacatenango@image...>
Hue in hsl() format is 0-360 and does not use %.


What I do in my scripts is put in version traps, so my users can have it either way, depending upon the version of IM they are running. My scripts have lots of these version traps for most everything that has changed over time.

I am not sure why the docs at http://www.imagemagick.org/MagickStudio/Color.html have not been changed to reflect this notation change, unless MagickStudio is still running the old convention.

I do take note of the original poster's comments about CSS standard is hue 0-360, but saturation and lightness is percent (only?). I would leave that to the IM developers to decide if they want to switch (back) to that format. The only way I can see to have it both ways, is to require % on each field where it is desired rather than just one % for any field means all fields are percent. This could be limited only to HSL and HSB color definitions, if desired or to RGB and CMYK as well. Or they could implement a new color representation, such as hslc/hsbc and hslac/hslbc to account for the CSS style convention, where c refers to the CSS style notation.

Nevertheless, any relevant script would still need to have version traps to account for all the changes in HSL/HSB color definitions.

Re: Mixed percentage & numeric color coordinates

Posted: 2015-08-01T16:11:40-07:00
by zweibieren
Thanks for a comprehensive reply. I am not glad, but at least heartened, to hear that the changes have had bigger impact on others than me.

Re: Mixed percentage & numeric color coordinates

Posted: 2015-08-15T09:08:07-07:00
by magick
ImageMagick does follow the CSS color standard so its a bug to treat the first value of a hsl() color as a percentage. We'll have a patch to fix the problem in ImageMagick 6.9.2-1 Beta by sometime tomorrow.