Discussion About New Linear and Non-linear Gray

Questions and postings pertaining to the development of ImageMagick, feature enhancements, and ImageMagick internals. ImageMagick source code and algorithms are discussed here. Usage questions which are too arcane for the normal user list should also be posted here.
Post Reply
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Discussion About New Linear and Non-linear Gray

Post by fmw42 »

At viewtopic.php?f=4&t=33265, non-linear colorspace has been introduced as sGray with colorspace Gray now being changed to linear.

This is fine with respect to reporting the colorspaces, but has several ramifications.

As before defining colors, srgb(...) and rgb(...) are still non-linear. So similarly sgray(...) and gray(...) shades are also non-linear.

I note that icc-colors, however, allow either non-linear or linear. This permits direct creation of non-linear colors or grays, which is nice.

Code: Select all

convert xc:"rgb(255,0,0)" non-linear_red.png
convert xc:"srgb(255,0,0)" non-linear_red.png
convert xc:"icc_color(srgb,1,0,0)" non-linear_red.png
but

Code: Select all

convert xc:"icc-color(rgb,1,0,0)" linear_red.png
Similarly,

Code: Select all

convert xc:"gray(255)" non-linear_white.png
convert xc:"sgray(255)" non-linear_white.png
convert xc:"icc-color(sgray,1)" non-linear_white.png
but

Code: Select all

convert xc:"icc-color(gray,1)" linear_white.png
(however, this currently is producing non-linear white and I believe is a bug)


There is one ramification of the current change that troubles me.

To create non-linear gray shades or convert color images to non-linear gray, one now uses the new colorspace sgray

Code: Select all

convert logo: -colorspace sgray logo_nonlinear_gray.png
And to create linear gray shades or convert a color image to linear gray, one now uses the old colorspace gray

Code: Select all

convert logo: -colorspace gray logo_linear_gray.png
This is not backgward compatible.

I would prefer that we keep -colorspace gray as non-linear for backward compatibility as I have many scripts that would need changing.

In order to then create linear gray shades or convert color to linear gray, I would suggest just keeping the existing -grayscale or -intensity and icc-color(gray, ...). For example

Code: Select all

convert logo: -grayscale rec709luminance logo_linear_gray.png
convert logo: -intensity rec709luminance -colorspace gray logo_linear_gray.png
convert xc:"icc_color(gray, 0.5) logo_linear_gray.png
or introduce something like -colorspace linear-gray.

And for non-linear, keep using -colorspace gray or -grayscale.

Code: Select all

convert logo: -colorspace gray logo_nonlinear_gray.png
convert logo: -grayscale rec709luma logo_nonlinear_gray.png
convert xc:"icc_color(sgray, 0.5) logo_nonlinear_gray.png
I would be interested in other opinions about this change. Any one else have an strong feelings either way about this.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Discussion About New sGray

Post by snibgo »

fmw42 wrote:And to create linear gray shades or convert a color image to linear gray, one now uses the old colorspace gray

Code: Select all

convert logo: -colorspace gray logo_linear_gray.png
This is not backgward compatible.
Yes, that struck me as ... well, how can I put this politely? "-colorspace Gray" is widely used to convert a non-linear colour image to a non-linear gray image. To change the behaviour of this common command is sheer ... {choose your own words}.

At a practical level, what do I do with all my pages and scripts? When users say my examples no longer work, do I patiently explain that "-colorspace gray" now does something different?

It seems that the new "sGray" will do what the old "Gray" does, and the new "Gray" will do something that wasn't available before. If so, then the obvious route is to call the new feature by a new name (eg "lGray" for "linear gray"), and the keep the old "Gray" as it was.

However, if they both do something different from the old Gray, then dream up new names for both, eg "lGray" and "sGray". And keep the old Gray as it is, perhaps with a "deprecated" warning.
snibgo's IM pages: im.snibgo.com
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: Discussion About New sGray

Post by magick »

Thanks for the problem report. We can reproduce it and will have a patch to fix it in GIT master branch @ https://github.com/ImageMagick/ImageMagick later today. The patch will be available in the beta releases of ImageMagick @ https://www.imagemagick.org/download/beta/ by sometime tomorrow.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Discussion About New sGray

Post by fmw42 »

Which issue is being changed or fixed? icc-color(gray...) or -colorspace gray.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Discussion About New sGray

Post by snibgo »

The problem that needs fixing isn't just "-colorspace", but all occurrences of "gray". For example:

Code: Select all

convert xc:gray(50%) g.png
This (until the recent anouncement) created a pixel with 50% values, in non-linear colourspace. I hope it will continue to do so in new versions.

Don't get me wrong -- I have no problems if IM wants to distinguish between linear and non-linear gray. That's fine. But changing existing commands, that's a real pain.
snibgo's IM pages: im.snibgo.com
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Discussion About New sGray

Post by fmw42 »

Snigbo: gray(50%), gray(128) and named grays such as gray50 are still non-linear. You can create linear or non-linear colors using icc-color(...).

Magick is going to revert -colorspace gray back to non-linear and introduce -colorspace linear-gray for linear gray in the next release.

I am just about to test the beta.
TedBaker
Posts: 50
Joined: 2017-10-10T14:14:55-07:00
Authentication code: 1151

Re: Discussion About New sGray

Post by TedBaker »

Why not leave the legacy names as is:

and introduce lGray, sGray and lRGB

then you have Gray, RGB, sRGB as legacy values

and new values of lGray for linear Gray,
sGray for Gray using the sRGB gamma
lRGB for linear RGB

basically make it very clear what you mean with the new terms but support the old

my 2 cents
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Discussion About New sGray

Post by fmw42 »

Yes, that is what is happening. -colorspace gray is back to non-linear and -colorspace linear-gray is now linear.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Discussion About New sGray

Post by fmw42 »

I have tested IM 6.9.9.29 non-hdri Q16 and IM 7.0.7.17 HDRI Q16 Mac OSX Sierra for the revised linear and non-linear gray colorspaces.

Non-linear gray is colorscpace=Gray. Linear gray is colorspace=LinearGray.

Differences might occur between HDRI and non-HDRI, when doing -colorspace gray or -colorspace linear-gray, for images that have 256 or less colors. HDRI conversion may create more colors and thus report sRGB or RGB rather than (palette) Gray or Linear-Gray.

Also differences will occur for example between PNG and TIFF, for example. PNG supports linear gray. TIFF does not. So PNG will show gamma=1, but TIF will show gamma=0.4545.

Also differences will occur for %[colorspace] vs identify -verbose Colorspace:, since the way I have structured the test, %[colorspace] is reporting the in-memory data and not the data stored in the actually saved file. Saved files may not support linear gray.

All forms of gray, namely, named grays, gray(...) and gray(...%) are non-linear. To create a linear gray color or gradient: you can use -colorspace LinearGray before saving the image. Or you can use icc-colors to create linear grays directly.

Code: Select all

convert -size 128x128 gradient:"gray0-gray100" -format "%[colorspace] %[gamma]\n" -write info: tmp1a.png
Gray 0.454545

identify -verbose tmp1a.png | grep -E "Colorspace: | Type: | Gamma:"
Colorspace: Gray
Type: Grayscale
Gamma: 0.454545

magick -size 128x128 gradient:"gray0-gray100" -format "%[colorspace] %[gamma]\n" -write info: tmp1b.png
Gray 0.454545

magick identify -verbose tmp1b.png | grep -E "Colorspace: | Type: | Gamma:"
Colorspace: Gray
Type: Grayscale
Gamma: 0.45455


convert -size 128x128 gradient:"gray(0%)-gray(100%)" -format "%[colorspace] %[gamma]\n" -write info: tmp1c.png
Gray 0.454545

identify -verbose tmp1c.png | grep -E "Colorspace: | Type: | Gamma:"
Image: tmp1c.png
  Colorspace: Gray
  Type: Grayscale
  Gamma: 0.45455


magick -size 128x128 gradient:"gray(0%)-gray(100%)" -format "%[colorspace] %[gamma]\n" -write info: tmp1d.png
Gray 0.454545

magick identify -verbose tmp1d.png | grep -E "Colorspace: | Type: | Gamma:"
Image: tmp1d.png
  Colorspace: Gray
  Type: Grayscale
  Gamma: 0.45455




convert -size 128x128 xc:"gray50" -format "%[colorspace] %[gamma]\n" -write info: tmp1a.png
Gray 0.454545

identify -verbose tmp1a.png | grep -E "Colorspace: | Type: | Gamma:"
Colorspace: Gray
Type: Grayscale
Gamma: 0.45455


magick -size 128x128 xc:"gray50" -format "%[colorspace] %[gamma]\n" -write info: tmp1b.png
Gray 0.454545

magick identify -verbose tmp1b.png | grep -E "Colorspace: | Type: | Gamma:"
Colorspace: Gray
Type: Grayscale
Gamma: 0.45455
 

convert -size 128x128 xc:"gray(50%)" -format "%[colorspace] %[gamma]\n" -write info: tmp1c.png
Gray 0.454545

identify -verbose tmp1c.png | grep -E "Colorspace: | Type: | Gamma:"
Image: tmp1c.png
  Colorspace: Gray
  Type: Grayscale
  Gamma: 0.45455


magick -size 128x128 xc:"gray(50%)" -format "%[colorspace] %[gamma]\n" -write info: tmp1d.png
Gray 0.454545

magick identify -verbose tmp1d.png | grep -E "Colorspace: | Type: | Gamma:"
Image: tmp1d.png
  Colorspace: Gray
  Type: Grayscale
  Gamma: 0.45455


convert logo: -colorspace gray logo.jpg
convert logo.jpg PNG24:logo.png
convert logo.png -format "%[colorspace]\n" info:
sRGB

identify -verbose logo.png | grep -E "Colorspace: | Type: | Gamma:"
  Colorspace: sRGB
  Type: Grayscale
  Gamma: 0.45455

magick logo: -colorspace gray logo.jpg
magick logo.jpg PNG24:logo.png
magick logo.png -format "%[colorspace]\n" info:
sRGB

magick identify -verbose logo.png | grep -E "Colorspace: | Type: | Gamma:"
  Colorspace: sRGB
  Type: Grayscale
  Gamma: 0.45455



convert logo: -colorspace gray logo.jpg
convert logo.jpg -type truecolor logo.tif
convert logo.tif -format "%[colorspace]\n" info:
sRGB

identify -verbose logo.png | grep -E "Colorspace: | Type: | Gamma:"
  Colorspace: sRGB
  Type: Grayscale
  Gamma: 0.45455


magick logo: -colorspace gray logo.jpg
magick logo.jpg -type truecolor logo.tif
magick logo.tif -format "%[colorspace]\n" info:
sRGB

magick identify -verbose logo.png | grep -E "Colorspace: | Type: | Gamma:"
  Colorspace: sRGB
  Type: Grayscale
  Gamma: 0.45455



convert logo: -colorspace Gray -format "%[colorspace] %[gamma]\n" -write info: logo_gray6.png
Gray 0.454545

identify -verbose logo_gray6.png | grep -E "Colorspace: | Type: | Gamma:"
  Colorspace: Gray
  Type: Grayscale
  Gamma: 0.45455

convert logo: -colorspace Linear-Gray -format "%[colorspace] %[gamma]\n" -write info: logo_lgray6.png
LinearGray 1

identify -verbose logo_lgray6.png | grep -E "Colorspace: | Type: | Gamma:"
  Colorspace: RGB
  Type: Grayscale
  Gamma: 1



magick logo: -colorspace Gray -format "%[colorspace] %[gamma]\n" -write info: logo_gray7.png
Gray 0.454545

magick identify -verbose logo_gray7.png | grep -E "Colorspace: | Type: | Gamma:"
  Colorspace: Gray
  Type: Grayscale
  Gamma: 0.45455

magick logo: -colorspace Linear-Gray -format "%[colorspace] %[gamma]\n" -write info: logo_lgray7.png
LinearGray 1

magick identify -verbose logo_lgray7.png | grep -E "Colorspace: | Type: | Gamma:"
  Colorspace: LinearGray
  Type: Grayscale
  Gamma: 1


convert logo: -colorspace Linear-Gray -format "%[colorspace] %[gamma]\n" -write info: logo_lgray6.tif
LinearGray 1

identify -verbose logo_lgray6.tif | grep -E "Colorspace: | Type: | Gamma:"
  Colorspace: Gray
  Type: Grayscale
 Gamma: 0.454545


magick logo: -colorspace Linear-Gray -format "%[colorspace] %[gamma]\n" -write info: logo_lgray7.tif
LinearGray 1

magick identify -verbose logo_lgray7.tif | grep -E "Colorspace: | Type: | Gamma:"
  Colorspace: Gray
  Type: Grayscale
 Gamma: 0.454545



convert xc:"rgb(255,0,0)" -format "%[colorspace] %[gamma]\n" -write info: non-linear_red.png
sRGB 0.454545

convert xc:"srgb(255,0,0)" -format "%[colorspace] %[gamma]\n" -write info: non-linear_red.png
sRGB 0.454545

convert xc:"gray(255)" -format "%[colorspace] %[gamma]\n" -write info: non-linear_red.png
Gray 0.454545

convert xc:"icc-color(lineargray,1)" -format "%[colorspace] %[gamma]\n" -write info: non-linear_white.png
LinearGray 1

convert xc:"icc-color(gray,1)" -format "%[colorspace] %[gamma]\n" -write info: linear_white.png
Gray 0.454545

convert xc:"icc-color(srgb,1,0,0)" -format "%[colorspace] %[gamma]\n" -write info: non-linear_red.png
sRGB 0.454545

convert xc:"icc-color(rgb,1,0,0)" -format "%[colorspace] %[gamma]\n" -write info: linear_red.png
RGB 1



convert -size 500x500 xc:gray50 -depth 8 -type truecolor -set colorspace:auto-grayscale off -format "%[colorspace] %[gamma]\n" -write info: test.jpg
sRGB 0.454545

identify -verbose test.jpg | grep -E "Colorspace: | Type: | Gamma:"
  Colorspace: sRGB
  Type: Grayscale
  Gamma: 0.454545


convert -size 500x500 xc:gray50 -depth 8 -type truecolor -define colorspace:auto-grayscale=off -format "%[colorspace] %[gamma]\n" -write info: test.jpg
sRGB 0.454545

identify -verbose test.jpg | grep -E "Colorspace: | Type: | Gamma:"
  Colorspace: sRGB
  Type: Grayscale
  Gamma: 0.454545
Post Reply