lcms-user Mailing List for Little cms color engine (Page 2)
An ICC-based CMM for color management
Brought to you by:
mm2
You can subscribe to this list here.
| 2001 |
Jan
|
Feb
|
Mar
|
Apr
(2) |
May
(15) |
Jun
(24) |
Jul
(9) |
Aug
(14) |
Sep
|
Oct
(12) |
Nov
(17) |
Dec
(31) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2002 |
Jan
(34) |
Feb
(7) |
Mar
(7) |
Apr
(16) |
May
(4) |
Jun
(14) |
Jul
(34) |
Aug
(54) |
Sep
(11) |
Oct
(25) |
Nov
(1) |
Dec
(6) |
| 2003 |
Jan
(27) |
Feb
(54) |
Mar
(23) |
Apr
(68) |
May
(82) |
Jun
(36) |
Jul
(45) |
Aug
(45) |
Sep
(49) |
Oct
(30) |
Nov
(65) |
Dec
(23) |
| 2004 |
Jan
(52) |
Feb
(52) |
Mar
(35) |
Apr
(38) |
May
(93) |
Jun
(22) |
Jul
(51) |
Aug
(50) |
Sep
(73) |
Oct
(28) |
Nov
(30) |
Dec
(51) |
| 2005 |
Jan
(22) |
Feb
(79) |
Mar
(38) |
Apr
(51) |
May
(95) |
Jun
(60) |
Jul
(56) |
Aug
(49) |
Sep
(22) |
Oct
(43) |
Nov
(15) |
Dec
(40) |
| 2006 |
Jan
(51) |
Feb
(31) |
Mar
(37) |
Apr
(25) |
May
(9) |
Jun
(13) |
Jul
(17) |
Aug
(66) |
Sep
(7) |
Oct
(12) |
Nov
(14) |
Dec
(31) |
| 2007 |
Jan
(18) |
Feb
(9) |
Mar
(22) |
Apr
(18) |
May
(5) |
Jun
(25) |
Jul
(2) |
Aug
(15) |
Sep
(12) |
Oct
(40) |
Nov
(10) |
Dec
(23) |
| 2008 |
Jan
(21) |
Feb
(56) |
Mar
(12) |
Apr
(23) |
May
(47) |
Jun
(75) |
Jul
(24) |
Aug
(2) |
Sep
(7) |
Oct
(26) |
Nov
(20) |
Dec
(16) |
| 2009 |
Jan
(14) |
Feb
(1) |
Mar
(29) |
Apr
(54) |
May
(18) |
Jun
(16) |
Jul
(5) |
Aug
(3) |
Sep
(38) |
Oct
(6) |
Nov
(25) |
Dec
(28) |
| 2010 |
Jan
(11) |
Feb
(26) |
Mar
(2) |
Apr
(10) |
May
(45) |
Jun
(94) |
Jul
(11) |
Aug
(32) |
Sep
(18) |
Oct
(37) |
Nov
(19) |
Dec
(34) |
| 2011 |
Jan
(21) |
Feb
(16) |
Mar
(16) |
Apr
(29) |
May
(17) |
Jun
(18) |
Jul
(7) |
Aug
(21) |
Sep
(10) |
Oct
(7) |
Nov
(15) |
Dec
(6) |
| 2012 |
Jan
(13) |
Feb
(16) |
Mar
(15) |
Apr
(12) |
May
(15) |
Jun
(31) |
Jul
(22) |
Aug
(15) |
Sep
(46) |
Oct
(21) |
Nov
(15) |
Dec
(33) |
| 2013 |
Jan
(19) |
Feb
(17) |
Mar
(31) |
Apr
(17) |
May
(27) |
Jun
(24) |
Jul
(26) |
Aug
(11) |
Sep
(9) |
Oct
(22) |
Nov
(14) |
Dec
(16) |
| 2014 |
Jan
(20) |
Feb
(66) |
Mar
(29) |
Apr
(13) |
May
(9) |
Jun
|
Jul
(11) |
Aug
(21) |
Sep
(15) |
Oct
(5) |
Nov
(5) |
Dec
(10) |
| 2015 |
Jan
(6) |
Feb
(26) |
Mar
(26) |
Apr
|
May
(9) |
Jun
(5) |
Jul
(5) |
Aug
(11) |
Sep
(8) |
Oct
|
Nov
|
Dec
|
| 2016 |
Jan
(3) |
Feb
|
Mar
(9) |
Apr
(3) |
May
(16) |
Jun
(26) |
Jul
(32) |
Aug
(27) |
Sep
(9) |
Oct
|
Nov
(4) |
Dec
(10) |
| 2017 |
Jan
(11) |
Feb
(44) |
Mar
(6) |
Apr
(8) |
May
(1) |
Jun
(2) |
Jul
(34) |
Aug
(28) |
Sep
(3) |
Oct
(9) |
Nov
(3) |
Dec
|
| 2018 |
Jan
(1) |
Feb
(5) |
Mar
(6) |
Apr
(1) |
May
(1) |
Jun
(2) |
Jul
|
Aug
(1) |
Sep
(6) |
Oct
|
Nov
(6) |
Dec
|
| 2019 |
Jan
(18) |
Feb
(16) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(7) |
Sep
(3) |
Oct
(10) |
Nov
(1) |
Dec
(3) |
| 2020 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(17) |
Jun
(23) |
Jul
|
Aug
(4) |
Sep
|
Oct
|
Nov
|
Dec
|
| 2021 |
Jan
(10) |
Feb
(3) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(5) |
Oct
|
Nov
(1) |
Dec
|
| 2022 |
Jan
(8) |
Feb
|
Mar
(9) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(13) |
Nov
(12) |
Dec
|
| 2023 |
Jan
|
Feb
(1) |
Mar
(9) |
Apr
|
May
(3) |
Jun
(5) |
Jul
(3) |
Aug
(8) |
Sep
|
Oct
|
Nov
(1) |
Dec
(9) |
| 2024 |
Jan
(8) |
Feb
|
Mar
(14) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2025 |
Jan
(1) |
Feb
(1) |
Mar
(1) |
Apr
(2) |
May
(5) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(3) |
Nov
(1) |
Dec
|
|
From: <mar...@li...> - 2024-03-15 17:54:03
|
Hi Paalanen,
Nice to contact you. Regarding your question, matrix shaper is only a very
limited subset, true ICC profiles uses CLUT. Also, matrix shaper does not
allow gamut mapping so it is better to avoid matrix-shaper whatever
possible.
I think there is a much better solution than replicating all lcms internals.
You have to implement thetrahedral interpolation on GPU. It is not a big
deal, in CUDA and OpenCL is trivial. You can use the lcms code as basis.
Then, when you want to do color management, just create a color transform
and sample all RGB to RGB gamut in a CLUT of 33 points. You could use more
points if wish so, but 33 is enough in most cases. Ignore the profiles
internals, it is nothing of your business:
cmsOpenProfileFromFile input
cmsOpenProfileFromFile output
cmsCreateTransform input to output in floating point float
for (r=0; r<255; r += 256/33)
for (g=0; g<255; g += 256/33)
for (b=0; b<255; b += 256/33)
{
cmsDoTransform rgb -> rgb_out
store in GPU CLUT
}
Close everything
Then, when you want to transform an image, just use this CLUT and
tethahedral interpolation to do the color matching. It is fast because it
happens in the GPU. It is simple because you have not to worry about the
internal representation of the profiles. It is scalable because you can add
more points to increase precision and it is portable. And all color
management features are working.
Don't mess with DToBxx neither with matrix shaper, otherwise you would end
replicating all lcms functionality. Don't try to oversimplify by using
matrix-shaper, those are not good for gamut mapping and have no intents.
Color management does not work by using matrix shaper.
Hope that helps
Marti Maria
The LittleCMS Project
https://www.littlecms.com
uetiwonder why are you takin such huge amount
> -----Original Message-----
> From: Pekka Paalanen <pek...@ha...>
> Sent: Friday, March 15, 2024 11:23 AM
> To: lcm...@li...
> Subject: [Lcms-user] Creating equivalent matrix-shaper and 3D LUT
profiles,
> problem with BPC
>
> Hi,
>
> I'm working on a Wayland compositor (Weston) to integrate LittleCMS in it.
I
> use LittleCMS to come up with the color transformation from ICC profiles,
> then extract and optimize the cmsPipeline, and implement it in OpenGL ES
3.0
> shaders.
>
> I have some difficulty in generating ICC profiles in Weston's test suite.
I want
> the test suite to exercise all code paths to ensure the color operations
are
> implemented correctly. I have separate code paths for matrices+curves and
3D
> LUTs. Which code path gets chosen depends on what processing blocks
> (cmsStage) an ICC file results in. Therefore, I would like to craft
identically
> behaving ICC files that hit the different code paths (the goal).
>
> Crafting matrix-shaper profiles is easy. Crafting an equivalent profile
that
> internally has a 3D LUT (DToB/BToD) is the problem. I can craft such an
ICC
> profile, but because I need to test with the perceptual rendering intent,
I
> should also include BPC between the zeros black point of a matrix-shaper
and
> the non-zero black point of the v4 perceptual PCS. Otherwise the
assumption
> that a perceptual v4 CLUT profile has the ICCv4 defined perceptual black
point
> does not hold, and the tests fail.
>
> Is my goal reasonable to begin with, or should I just accept that
exercising the
> different Weston GL ES code paths by means of different ICC profiles
cannot
> lead to identical results and I need to define my expected test results
> separately for each case?
>
> If my goal is reasonable, then what would be a good way to add the
required
> BPC? Can I make LittleCMS compute it for me, or should I just copy the BPC
> algorithm from LittleCMS?
>
> I've tried creating the DToB/BToD test profile 3D LUT by creating a chain
of the
> usual matrix-shaper profile and the abstract XYZ profile and sampling
that, but
> now I'm convinced that I cannot get BPC applied that way, not with the XYZ
> profile at least.
>
>
> Thanks,
> pq
|
|
From: Pekka P. <pek...@ha...> - 2024-03-15 16:06:56
|
On Fri, 15 Mar 2024 15:16:13 +0100
<mar...@li...> wrote:
> Hi Paalanen,
>
> Nice to contact you. Regarding your question, matrix shaper is only a very
> limited subset, true ICC profiles uses CLUT. Also, matrix shaper does not
> allow gamut mapping so it is better to avoid matrix-shaper whatever
> possible.
>
> I think there is a much better solution than replicating all lcms internals.
> You have to implement thetrahedral interpolation on GPU. It is not a big
> deal, in CUDA and OpenCL is trivial. You can use the lcms code as basis.
>
> Then, when you want to do color management, just create a color transform
> and sample all RGB to RGB gamut in a CLUT of 33 points. You could use more
> points if wish so, but 33 is enough in most cases. Ignore the profiles
> internals, it is nothing of your business:
>
> cmsOpenProfileFromFile input
> cmsOpenProfileFromFile output
>
> cmsCreateTransform input to output in floating point float
>
> for (r=0; r<255; r += 256/33)
> for (g=0; g<255; g += 256/33)
> for (b=0; b<255; b += 256/33)
> {
> cmsDoTransform rgb -> rgb_out
> store in GPU CLUT
> }
>
> Close everything
>
> Then, when you want to transform an image, just use this CLUT and
> tethahedral interpolation to do the color matching. It is fast because it
> happens in the GPU. It is simple because you have not to worry about the
> internal representation of the profiles. It is scalable because you can add
> more points to increase precision and it is portable. And all color
> management features are working.
Hi Marti,
I wish I could share your optimism.
Do you know if that is also enough when one side is BT.2020/PQ encoded
HDR and the other side can be anything, including an optical encoding?
If you have any paper to point to that suggests a 3D LUT is all you
need, I would be exhilarated, and I would tell the Linux display driver
engineers to forward that to their hardware engineers, so we wouldn't
have do things the hard way in the future.
I know, ICC profiles cannot represent HDR spaces in a good way, unless
maybe with the most recent addition of CICP tags. However, I don't need
to represent such things as valid ICC conformant profiles, they will
never escape Weston's processes. I'm planning to abuse the
cmsHPROFILE/cmsPipeline machinery that LittleCMS already has in an
extendable form instead of inventing my own, and craft such
cmsHPROFILEs that a chain of them results in the pipeline I need. The
reason I originally went this way is because I need to be able to
handle source/destination profile combinations where one of them is a
valid ICC profile file, and the other is a DTV video format description
like HDR10 with HDR static metadata. Of course, I need to support a
pure ICC workflow too.
We want to make an explicit trip through an optically encoded
intermediate space for blending, so transformations between two
electrical encodings will be rare. We are also likely to get
application content in optical encoding, optical scRGB sounds to be
popular in (Windows) HDR games.
My experience with LUTs is that even something as simple as the inverse
of power 2.2 curve will need a ridiculous number of uniformly
distributed LUT elements to reach any kind of usable precision. For 8
bit-per-channel electrical encoding precision, with 4096 elements in
optical domain the maximum error is still bigger than +/- 1 code point.
I believe the perceptual quantizer curve is even more extreme. We will
be adding the missing curve types as LittleCMS plugins, like the PQ and
HLG curves, since they would be far too expensive as LUTs.
Luckily though, I can choose the compositor blending space such that
that kind of curves will appear alone and not need channel mixing at
that stage. But a 1D LUT is probably not good enough even then, which
is why display controller hardware designers are inventing things like
fixed-function curves and non-uniformly distributed 1D LUTs.
I suspect that if a 3D LUT could do everything with reasonable
precision / storage trade-off, the display controller hardware
designers would simply put a 3D LUT on the card instead of all the
various matrix, fixed curve, and LUT elements they are having now, in
addition to some 3D LUT elements. By this I mean composition
off-loading to display controllers, a.k.a Linux DRM with multiple KMS
planes that the hardware blends together live during a scanout cycle.
My ultimate goal as a Weston compositor developer is to aim at
off-loading all color processing to the display controller, and using a
GPU only as a fallback. That means I need to match the fixed-function
hardware capabilities as closely as possible, and they seem to be
having a series of elements. See for example the "DCN 3.0 family color
caps and mapping" diagram just above
https://dri.freedesktop.org/docs/drm/gpu/amdgpu/display/display-manager.html#blend-mode-properties .
Hence, the idea of just collapsing everything into a single giant 3D
LUT does not seem to fit, as easy as it would make my life.
> Don't mess with DToBxx neither with matrix shaper, otherwise you would end
> replicating all lcms functionality. Don't try to oversimplify by using
> matrix-shaper, those are not good for gamut mapping and have no intents.
> Color management does not work by using matrix shaper.
So, to get back to the point.
I'm starting from a matrix-shaper profile in the tests, because a
matrix-shaper profile carries all the stage types Weston currently
recognises and optimises. This is the way I can easily test the 3x1D
LUT - matrix - 3x1D LUT path, and the optimiser. I have understood that
matrix-shaper profiles are common as SDR display profiles when you
don't bother profiling the display. Also television broadcast standards
use essentially matrix-shaper types.
All I'm doing here is to check that the mathematics is coded correctly.
When Weston fails to recognise a cmsStage or fails to map the optimised
pipeline to its internal fixed-function pipeline (which mimics what DRM
KMS exposes, so that we can more easily off-load the pipeline to KMS in
the future), it falls back to a 3D LUT. I need an ICC profile file that
contains such stages that force Weston to fall back. A literal 3D LUT
stage is the best option, because I want to test Weston's 3D LUT path.
When I use a 3D LUT in an ICC file, I suddenly also need to adhere to
the perceptual PCS definition of the black point as well. The fact that
matrix-shaper profiles do not behave the same is the headache here.
I did get it to work, by copying 10-20 lines of code from
ComputeBlackPointCompensation() depending on if you count the comments.
I was hoping to not need to do that and just tell LittleCMS to add BPC
compensation in the transformation.
I haven't tried to replace my matrix-shaper test profiles with a DToB
profile using a matrix and a curveset, but then I would need to adhere
to the perceptual PCS black point already there. I think it would just
move my problem from one place to another instead of solving it.
Thanks,
pq
>
> Hope that helps
>
> Marti Maria
> The LittleCMS Project
> https://www.littlecms.com
>
>
>
> uetiwonder why are you takin such huge amount
>
> > -----Original Message-----
> > From: Pekka Paalanen <pek...@ha...>
> > Sent: Friday, March 15, 2024 11:23 AM
> > To: lcm...@li...
> > Subject: [Lcms-user] Creating equivalent matrix-shaper and 3D LUT
> profiles,
> > problem with BPC
> >
> > Hi,
> >
> > I'm working on a Wayland compositor (Weston) to integrate LittleCMS in it.
> I
> > use LittleCMS to come up with the color transformation from ICC profiles,
> > then extract and optimize the cmsPipeline, and implement it in OpenGL ES
> 3.0
> > shaders.
> >
> > I have some difficulty in generating ICC profiles in Weston's test suite.
> I want
> > the test suite to exercise all code paths to ensure the color operations
> are
> > implemented correctly. I have separate code paths for matrices+curves and
> 3D
> > LUTs. Which code path gets chosen depends on what processing blocks
> > (cmsStage) an ICC file results in. Therefore, I would like to craft
> identically
> > behaving ICC files that hit the different code paths (the goal).
> >
> > Crafting matrix-shaper profiles is easy. Crafting an equivalent profile
> that
> > internally has a 3D LUT (DToB/BToD) is the problem. I can craft such an
> ICC
> > profile, but because I need to test with the perceptual rendering intent,
> I
> > should also include BPC between the zeros black point of a matrix-shaper
> and
> > the non-zero black point of the v4 perceptual PCS. Otherwise the
> assumption
> > that a perceptual v4 CLUT profile has the ICCv4 defined perceptual black
> point
> > does not hold, and the tests fail.
> >
> > Is my goal reasonable to begin with, or should I just accept that
> exercising the
> > different Weston GL ES code paths by means of different ICC profiles
> cannot
> > lead to identical results and I need to define my expected test results
> > separately for each case?
> >
> > If my goal is reasonable, then what would be a good way to add the
> required
> > BPC? Can I make LittleCMS compute it for me, or should I just copy the BPC
> > algorithm from LittleCMS?
> >
> > I've tried creating the DToB/BToD test profile 3D LUT by creating a chain
> of the
> > usual matrix-shaper profile and the abstract XYZ profile and sampling
> that, but
> > now I'm convinced that I cannot get BPC applied that way, not with the XYZ
> > profile at least.
> >
> >
> > Thanks,
> > pq
>
|
|
From: Pekka P. <pek...@ha...> - 2024-03-15 11:21:40
|
Hi, I'm working on a Wayland compositor (Weston) to integrate LittleCMS in it. I use LittleCMS to come up with the color transformation from ICC profiles, then extract and optimize the cmsPipeline, and implement it in OpenGL ES 3.0 shaders. I have some difficulty in generating ICC profiles in Weston's test suite. I want the test suite to exercise all code paths to ensure the color operations are implemented correctly. I have separate code paths for matrices+curves and 3D LUTs. Which code path gets chosen depends on what processing blocks (cmsStage) an ICC file results in. Therefore, I would like to craft identically behaving ICC files that hit the different code paths (the goal). Crafting matrix-shaper profiles is easy. Crafting an equivalent profile that internally has a 3D LUT (DToB/BToD) is the problem. I can craft such an ICC profile, but because I need to test with the perceptual rendering intent, I should also include BPC between the zeros black point of a matrix-shaper and the non-zero black point of the v4 perceptual PCS. Otherwise the assumption that a perceptual v4 CLUT profile has the ICCv4 defined perceptual black point does not hold, and the tests fail. Is my goal reasonable to begin with, or should I just accept that exercising the different Weston GL ES code paths by means of different ICC profiles cannot lead to identical results and I need to define my expected test results separately for each case? If my goal is reasonable, then what would be a good way to add the required BPC? Can I make LittleCMS compute it for me, or should I just copy the BPC algorithm from LittleCMS? I've tried creating the DToB/BToD test profile 3D LUT by creating a chain of the usual matrix-shaper profile and the abstract XYZ profile and sampling that, but now I'm convinced that I cannot get BPC applied that way, not with the XYZ profile at least. Thanks, pq |
|
From: Tom L. <to...@ke...> - 2024-01-30 00:09:07
|
<div dir='auto'><div dir="auto">On 29 Jan 2024 21:33, Adrian Knagg-Baugh <aje...@gm...> wrote:<br></div><div><div class="elided-text"><blockquote style="margin:0 0 0 0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Hi,<br></div><div><br></div><div>I have extracted the chromaticity xy coordinates from a cmsHPROFILE as follows:</div><div><br> cmsCIEXYZ *red;<br> cmsCIEXYZ *green;<br> cmsCIEXYZ *blue;<br> red = cmsReadTag (profile, cmsSigRedColorantTag);<br> green = cmsReadTag (profile, cmsSigGreenColorantTag);<br> blue = cmsReadTag (profile, cmsSigBlueColorantTag);<br></div><div></div> cmsXYZ2xyY(&redxyY, &red);<br> cmsXYZ2xyY(&greenxyY, &green);<br><div> cmsXYZ2xyY(&bluexyY, &blue);</div><div><br></div><div>However, if the profile I do this to is a sRGB profile made with chromaticities from the cmsCIExyYTRIPLE {<!-- -->{0.639998686, 0.330010138, 1.0}, {0.300003784, 0.600003357, 1.0}, {0.150002046, 0.059997204, 1.0}}, and the standard sRGB whitepoint cmsCIExyY d65_srgb_adobe_specs = {0.3127, 0.3290, 1.0}; I don't get back the same coordinates. Instead I get:<br></div><div><br></div><div><span style="font-family:monospace"><span style="color:rgb( 0 , 0 , 0 );background-color:rgb( 255 , 255 , 255 )">redxyY x: 0.648438, y: 0.330868, Y: 0.222488
</span><br>greenxyY x: 0.321176, y: 0.597877, Y: 0.716904
<br>bluexyY x: 0.155899, y: 0.066051, Y: 0.060608
<br></span></div><div><span style="font-family:'arial' , sans-serif"><br></span></div><div><span style="font-family:'arial' , sans-serif">What's going on here: is there something I'm not accounting for? And is there a more correct way to read the original chromaticities back out of a profile?<br></span></div><div><span style="font-family:'arial' , sans-serif"><br></span></div><div><span style="font-family:'arial' , sans-serif">Thanks,</span></div><div><span style="font-family:'arial' , sans-serif"><br></span></div><div><span style="font-family:'arial' , sans-serif">Adrian.<br></span></div><br></div>
</blockquote></div><br></div><div dir="auto">Adrian,</div><div dir="auto"><br></div><div dir="auto">red, green and blue are already pointers, so you shouldn't be taking their address.<div dir="auto"><br></div><div dir="auto">i.e. remove the &s</div><div dir="auto"><br></div><div dir="auto">Surprised your compiler didn't warn about this?</div><div dir="auto"><br></div><div dir="auto">Cheers</div></div></div> |
|
From: <mar...@li...> - 2024-01-29 22:38:01
|
Hello, > is there something I'm not accounting for? And is there a more correct way to read the original chromaticities back out of a profile? You are assuming the internals of ICC profiles works in a way they don’t. The cmsSigXXXColorantTag tags does NOT contain direct information on the primaries, numbers are “cooked” and it is certainly possible for those tags to be missing on some profiles. You should avoid reading tags directly as much as possible. Instead, use an absolute colorimetric transform with no observer adaptation to get the primaries. This would work no matter which profile type are you using. Here an example by using the transicc tool, you can do the same creating a transform with absolute colorimetric intent making sure to set the observer adaptation state to 0 first. I am trying to recover sRGB red primary: marti@I7:~$ transicc -t3 -d0 -i*sRGB -o*XYZ LittleCMS ColorSpace conversion calculator - 5.1 [LittleCMS 2.16] Copyright (c) 1998-2023 Marti Maria Saguer. See COPYING file for details. Enter values, 'q' to quit R? 255 G? 0 B? 0 X=41.2391 Y=21.2639 Z=1.9331 You convert this XYZ of (41.2391, 21.2639, 1.9331) to xyY, for example using this link: http://www.brucelindbloom.com/ColorCalculator.html xyY = (0.6400, 0.3300, 21.2639) Which corresponds to the Rec709 chromaticity of red. Hope that helps Marti Maria The LittleCMS Project https://www.littlecms.com From: Adrian Knagg-Baugh <aje...@gm...> Sent: Monday, January 29, 2024 10:34 PM To: lcm...@li... Subject: [Lcms-user] Need help recovering the chromaticities that a profile was made with Hi, I have extracted the chromaticity xy coordinates from a cmsHPROFILE as follows: cmsCIEXYZ *red; cmsCIEXYZ *green; cmsCIEXYZ *blue; red = cmsReadTag (profile, cmsSigRedColorantTag); green = cmsReadTag (profile, cmsSigGreenColorantTag); blue = cmsReadTag (profile, cmsSigBlueColorantTag); cmsXYZ2xyY(&redxyY, &red); cmsXYZ2xyY(&greenxyY, &green); cmsXYZ2xyY(&bluexyY, &blue); However, if the profile I do this to is a sRGB profile made with chromaticities from the cmsCIExyYTRIPLE {{0.639998686, 0.330010138, 1.0}, {0.300003784, 0.600003357, 1.0}, {0.150002046, 0.059997204, 1.0}}, and the standard sRGB whitepoint cmsCIExyY d65_srgb_adobe_specs = {0.3127, 0.3290, 1.0}; I don't get back the same coordinates. Instead I get: redxyY x: 0.648438, y: 0.330868, Y: 0.222488 greenxyY x: 0.321176, y: 0.597877, Y: 0.716904 bluexyY x: 0.155899, y: 0.066051, Y: 0.060608 What's going on here: is there something I'm not accounting for? And is there a more correct way to read the original chromaticities back out of a profile? Thanks, Adrian. |
|
From: Adrian Knagg-B. <aje...@gm...> - 2024-01-29 22:07:39
|
Thank you for the explanation. Yes, that's great, I will create a transform from profile to XYZ, use it to transform each RGB primary using absolute colorimetric, and then convert to xyY straightforwardly. Thanks again, Adrian. On Mon, 29 Jan 2024, 22:02 , <mar...@li...> wrote: > Hello, > > > > > is there something I'm not accounting for? And is there a more correct > way to read the original chromaticities back out of a profile? > > > > You are assuming the internals of ICC profiles works in a way they don’t. > The cmsSigXXXColorantTag tags does NOT contain direct information on the > primaries, numbers are “cooked” and it is certainly possible for those tags > to be missing on some profiles. > > > > You should avoid reading tags directly as much as possible. Instead, use > an absolute colorimetric transform with no observer adaptation to get the > primaries. This would work no matter which profile type are you using. > > > > Here an example by using the transicc tool, you can do the same creating a > transform with absolute colorimetric intent making sure to set the observer > adaptation state to 0 first. I am trying to recover sRGB red primary: > > > > marti@I7:~$ transicc -t3 -d0 -i*sRGB -o*XYZ > > LittleCMS ColorSpace conversion calculator - 5.1 [LittleCMS 2.16] > > Copyright (c) 1998-2023 Marti Maria Saguer. See COPYING file for details. > > > > Enter values, 'q' to quit > > R? 255 > > G? 0 > > B? 0 > > > > X=41.2391 Y=21.2639 Z=1.9331 > > > > You convert this XYZ of (41.2391, 21.2639, 1.9331) to xyY, for example > using this link: http://www.brucelindbloom.com/ColorCalculator.html > > > > xyY = (0.6400, 0.3300, 21.2639) Which corresponds to the Rec709 > chromaticity of red. > > > > Hope that helps > > > > Marti Maria > > The LittleCMS Project > > https://www.littlecms.com > > > > > > > > > > *From:* Adrian Knagg-Baugh <aje...@gm...> > *Sent:* Monday, January 29, 2024 10:34 PM > *To:* lcm...@li... > *Subject:* [Lcms-user] Need help recovering the chromaticities that a > profile was made with > > > > Hi, > > > > I have extracted the chromaticity xy coordinates from a cmsHPROFILE as > follows: > > > cmsCIEXYZ *red; > cmsCIEXYZ *green; > cmsCIEXYZ *blue; > red = cmsReadTag (profile, cmsSigRedColorantTag); > green = cmsReadTag (profile, cmsSigGreenColorantTag); > blue = cmsReadTag (profile, cmsSigBlueColorantTag); > > cmsXYZ2xyY(&redxyY, &red); > cmsXYZ2xyY(&greenxyY, &green); > > cmsXYZ2xyY(&bluexyY, &blue); > > > > However, if the profile I do this to is a sRGB profile made with > chromaticities from the cmsCIExyYTRIPLE {{0.639998686, 0.330010138, 1.0}, > {0.300003784, 0.600003357, 1.0}, {0.150002046, 0.059997204, 1.0}}, and the > standard sRGB whitepoint cmsCIExyY d65_srgb_adobe_specs = {0.3127, 0.3290, > 1.0}; I don't get back the same coordinates. Instead I get: > > > > redxyY x: 0.648438, y: 0.330868, Y: 0.222488 > greenxyY x: 0.321176, y: 0.597877, Y: 0.716904 > bluexyY x: 0.155899, y: 0.066051, Y: 0.060608 > > > > What's going on here: is there something I'm not accounting for? And is > there a more correct way to read the original chromaticities back out of a > profile? > > > > Thanks, > > > > Adrian. > > > |
|
From: Adrian Knagg-B. <aje...@gm...> - 2024-01-29 21:34:10
|
Hi,
I have extracted the chromaticity xy coordinates from a cmsHPROFILE as
follows:
cmsCIEXYZ *red;
cmsCIEXYZ *green;
cmsCIEXYZ *blue;
red = cmsReadTag (profile, cmsSigRedColorantTag);
green = cmsReadTag (profile, cmsSigGreenColorantTag);
blue = cmsReadTag (profile, cmsSigBlueColorantTag);
cmsXYZ2xyY(&redxyY, &red);
cmsXYZ2xyY(&greenxyY, &green);
cmsXYZ2xyY(&bluexyY, &blue);
However, if the profile I do this to is a sRGB profile made with
chromaticities from the cmsCIExyYTRIPLE {{0.639998686, 0.330010138, 1.0},
{0.300003784, 0.600003357, 1.0}, {0.150002046, 0.059997204, 1.0}}, and the
standard sRGB whitepoint cmsCIExyY d65_srgb_adobe_specs = {0.3127, 0.3290,
1.0}; I don't get back the same coordinates. Instead I get:
redxyY x: 0.648438, y: 0.330868, Y: 0.222488
greenxyY x: 0.321176, y: 0.597877, Y: 0.716904
bluexyY x: 0.155899, y: 0.066051, Y: 0.060608
What's going on here: is there something I'm not accounting for? And is
there a more correct way to read the original chromaticities back out of a
profile?
Thanks,
Adrian.
|
|
From: <mar...@li...> - 2024-01-08 10:13:55
|
Hi, >ie JDK could (SFAICS) change to specify the flag only when both src and dest have alpha. >I don't know when we actually need it when there's no alpha. Sergey ? That would solve all issues. Problem is, the code has no idea on how alpha should be interpreted, and this includes initializing. So, whatever I do to initialize alpha would be wrong in some cases. At that point I think it is better just flagging the error and let’s user to decide. Please note if you don’t specify the flag, the dest alpha channel is untouched, so the caller is responsible of initializing it. If you specify the flag, then the destination alpha channel is initialized by the CMM by copying it from source. The difference is when using the flag you can just malloc the dest memory, without the flag you have to process it before calling cmsDoTransform. Regards Marti Maria The LittleCMS Project <https://www.littlecms.com> https://www.littlecms.com From: Philip Race <phi...@or...> Sent: Friday, January 5, 2024 8:55 PM To: mar...@li...; Lcm...@li... Subject: Re: [Lcms-user] LCMS 2.16: CMMException: LCMS error 13: Mismatched alpha channels On 1/4/24 1:19 AM, mar...@li... <mailto:mar...@li...> wrote: Hi Phil, The reason was to prevent using this flag when the output has alpha channel and there is no source alpha. Specifically that case ? The JDK code currently and only relies on the opposite case, but the check as written allows neither. Other examples are different number of alpha channels. It is not clear what to do with the alpha in such cases. Should lcms initialize the excess with zero? Some folks began to have ideas of adding a new interface to init spare alpha channels so I just applied Occam’s razor. I am open to changes as long as they make sense. The actual implementation complains if the request cannot be accomplished, user specify to copy alpha and there is no alpha or the number of channels is different, an error is triggered. I guess you don’t like this being reported as an error. Ignoring the request seems also not right because user may think it is being performed whilst is really not. What should I do? Mainly I'd like some quick clarity so we can decide if we should change JDK code or wait for an update to LCMS. I can see the argument that specifying "copy alpha" is inconsistent with "there's no alpha to copy from", or "there's nowhere to copy the alpha to". And I can also see that it could easily be a mistake on the part of the app, that is best flagged in an upfront way. But if there's a sensible default action in some subset of these cases, that's documented and easily understood, meaning not loaded with exceptions and caveats, which would allow the existing usage to function properly, that might be preferable. I am not sure that either choice (keep the check as is, or relax it) would make what Sergey is asking for impossible, but I'll defer to him to comment on that. ie JDK could (SFAICS) change to specify the flag only when both src and dest have alpha. I don't know when we actually need it when there's no alpha. Sergey ? -phil. Regards Marti Maria The LittleCMS Project <https://www.littlecms.com> https://www.littlecms.com From: Philip Race <mailto:phi...@or...> <phi...@or...> Sent: Wednesday, January 3, 2024 9:00 PM To: Lcm...@li... <mailto:Lcm...@li...> Subject: [Lcms-user] LCMS 2.16: CMMException: LCMS error 13: Mismatched alpha channels JDK is using the flag cmsFLAGS_COPY_ALPHA. It is specified in a few cases including if the source has alpha but the destination is opaque, expecting that the alpha channel will be ignored. Here's where JDK started using the flag https://github.com/openjdk/jdk/commit/16acfafb#diff-eed6ddb15e9c5bdab9fc3b3930d5d959966165d9622ddd293e8572489adea98b But in LCMS 2.16 there's a new check that this is running afoul of. https://github.com/mm2/Little-CMS/commit/e55b6fa4d3c5b7e08d9e4bc8c803a79ca908b5a4#diff-3627f903d37617a227e71f0ee1[…]2629b5ee838707e3fcd7dcb46e762f4e It seems to me that likely we could just drop specifying cmsFLAGS_COPY_ALPHA in this case, but I can't find any background information on the reason for the change in LCMS, or awareness that it might be a compatibility issue. Thoughts / comments ? -phil. |
|
From: Philip R. <phi...@or...> - 2024-01-05 20:00:12
|
On 1/4/24 1:19 AM, mar...@li... wrote: > > Hi Phil, > > The reason was to prevent using this flag when the output has alpha > channel and there is no source alpha. > Specifically that case ? The JDK code currently and only relies on the opposite case, but the check as written allows neither. > Other examples are different number of alpha channels. It is not clear > what to do with the alpha in such cases. Should lcms initialize the > excess with zero? > > Some folks began to have ideas of adding a new interface to init spare > alpha channels so I just applied Occam’s razor. > > I am open to changes as long as they make sense. The actual > implementation complains if the request cannot be accomplished, user > specify to copy alpha and there is no alpha or the number of channels > is different, an error is triggered. > > I guess you don’t like this being reported as an error. Ignoring the > request seems also not right because user may think it is being > performed whilst is really not. > > What should I do? > Mainly I'd like some quick clarity so we can decide if we should change JDK code or wait for an update to LCMS. I can see the argument that specifying "copy alpha" is inconsistent with "there's no alpha to copy from", or "there's nowhere to copy the alpha to". And I can also see that it could easily be a mistake on the part of the app, that is best flagged in an upfront way. But if there's a sensible default action in some subset of these cases, that's documented and easily understood, meaning not loaded with exceptions and caveats, which would allow the existing usage to function properly, that might be preferable. I am not sure that either choice (keep the check as is, or relax it) would make what Sergey is asking for impossible, but I'll defer to him to comment on that. ie JDK could (SFAICS) change to specify the flag only when both src and dest have alpha. I don't know when we actually need it when there's no alpha. Sergey ? -phil. > Regards > > Marti Maria > > The LittleCMS Project > > https://www.littlecms.com <https://www.littlecms.com> > > *From:* Philip Race <phi...@or...> > *Sent:* Wednesday, January 3, 2024 9:00 PM > *To:* Lcm...@li... > *Subject:* [Lcms-user] LCMS 2.16: CMMException: LCMS error 13: > Mismatched alpha channels > > JDK is using the flag cmsFLAGS_COPY_ALPHA. It is specified in a few > cases including if > the source has alpha but the destination is opaque, expecting that the > alpha channel will be ignored. > > Here's where JDK started using the flag > https://github.com/openjdk/jdk/commit/16acfafb#diff-eed6ddb15e9c5bdab9fc3b3930d5d959966165d9622ddd293e8572489adea98b > > But in LCMS 2.16 there's a new check that this is running afoul of. > https://github.com/mm2/Little-CMS/commit/e55b6fa4d3c5b7e08d9e4bc8c803a79ca908b5a4#diff-3627f903d37617a227e71f0ee1[…]2629b5ee838707e3fcd7dcb46e762f4e > > It seems to me that likely we could just drop specifying > cmsFLAGS_COPY_ALPHA in this case, > but I can't find any background information on the reason for the > change in LCMS, or awareness that > it might be a compatibility issue. > > Thoughts / comments ? > > -phil. > |
|
From: <mar...@li...> - 2024-01-04 11:49:04
|
Hi Phil, The reason was to prevent using this flag when the output has alpha channel and there is no source alpha. Other examples are different number of alpha channels. It is not clear what to do with the alpha in such cases. Should lcms initialize the excess with zero? Some folks began to have ideas of adding a new interface to init spare alpha channels so I just applied Occam’s razor. I am open to changes as long as they make sense. The actual implementation complains if the request cannot be accomplished, user specify to copy alpha and there is no alpha or the number of channels is different, an error is triggered. I guess you don’t like this being reported as an error. Ignoring the request seems also not right because user may think it is being performed whilst is really not. What should I do? Regards Marti Maria The LittleCMS Project <https://www.littlecms.com> https://www.littlecms.com From: Philip Race <phi...@or...> Sent: Wednesday, January 3, 2024 9:00 PM To: Lcm...@li... Subject: [Lcms-user] LCMS 2.16: CMMException: LCMS error 13: Mismatched alpha channels JDK is using the flag cmsFLAGS_COPY_ALPHA. It is specified in a few cases including if the source has alpha but the destination is opaque, expecting that the alpha channel will be ignored. Here's where JDK started using the flag https://github.com/openjdk/jdk/commit/16acfafb#diff-eed6ddb15e9c5bdab9fc3b3930d5d959966165d9622ddd293e8572489adea98b But in LCMS 2.16 there's a new check that this is running afoul of. https://github.com/mm2/Little-CMS/commit/e55b6fa4d3c5b7e08d9e4bc8c803a79ca908b5a4#diff-3627f903d37617a227e71f0ee1[…]2629b5ee838707e3fcd7dcb46e762f4e It seems to me that likely we could just drop specifying cmsFLAGS_COPY_ALPHA in this case, but I can't find any background information on the reason for the change in LCMS, or awareness that it might be a compatibility issue. Thoughts / comments ? -phil. |
|
From: Philip R. <phi...@or...> - 2024-01-03 20:00:29
|
JDK is using the flag cmsFLAGS_COPY_ALPHA. It is specified in a few cases including if the source has alpha but the destination is opaque, expecting that the alpha channel will be ignored. Here's where JDK started using the flag https://github.com/openjdk/jdk/commit/16acfafb#diff-eed6ddb15e9c5bdab9fc3b3930d5d959966165d9622ddd293e8572489adea98b But in LCMS 2.16 there's a new check that this is running afoul of. https://github.com/mm2/Little-CMS/commit/e55b6fa4d3c5b7e08d9e4bc8c803a79ca908b5a4#diff-3627f903d37617a227e71f0ee1[…]2629b5ee838707e3fcd7dcb46e762f4e It seems to me that likely we could just drop specifying cmsFLAGS_COPY_ALPHA in this case, but I can't find any background information on the reason for the change in LCMS, or awareness that it might be a compatibility issue. Thoughts / comments ? -phil. |
|
From: <mar...@li...> - 2023-12-29 14:41:43
|
Hi, >From your explanation, it seems to me that the transformation you want has nothing to do with color management. You know nothing about the L* of your grayscale and need only some scaling. I would rather use simple math in this case: Gray_out = (Gray_in * 40) /51 + 40; You could just use a for() loop. This is going to be faster that using any color management routines. Regards Marti Maria The LittleCMS Project https://www.littlecms.com > -----Original Message----- > From: flap <fb...@oh...> > Sent: Friday, December 29, 2023 12:06 PM > To: lcm...@li... > Subject: [Lcms-user] How does a transformation work > > Hi list, > > what I want: an 8 bit grey-scale output for my printer, where the input dot > values (0 … 255) are scaled and limited to values of 40 … 240 (…just an > example). > > So I created a simple test input data (256 elements of unsigned char) with a > linear ramp from 0 (at index 0) … 255 (at index 255). > > And I created an array with 4096 short entries beginning with 40 (* 256 for > unsigned short) and ramp up linear to 240 (* 256 for unsigned short) and feed > it into cmsBuildTabulatedToneCurve16() and cmsCreateGrayProfile() with > cmsD50_xyY() as its whitepoint (for the output profile). > > For the input profile I used cmsBuildGamma() with a value of 1.0 and > cmsCreateGrayProfile() with cmsD50_xyY(). > > After creating the transformation with cmsCreateTransform() with > input/output types both TYPE_GRAY_8 and an intent of INTENT_PERCEPTUAL > and applying this transformation with cmsDoTransformLineStride () to my > simple input data, the output result is still almost linear from 0 to 255 and not > limited to 40 … 240. > > So, I think I'm using the tone curves in a wrong way. But where is my mistake? > > Cheers, > Jürgen > > > > > _______________________________________________ > Lcms-user mailing list > Lcm...@li... > https://lists.sourceforge.net/lists/listinfo/lcms-user |
|
From: <mar...@li...> - 2023-12-29 14:21:17
|
Ok,
The procedure to create a gray profile is simple.
First measure the transfer function of your gray device to XYZ. That could be a gamma curve or anything.
Then measure the white point of your gray space. The adaptation to D50 is already done by lcms.
Then create a tone curve with your transfer function.
Finally, by using white point and curve, create a profile.
Please note you cannot map contone values for input to output since the output profile is unknown. So, you cannot map 0 to 40 and 255 to 240. You can only characterize which XYZ you get with gray = 0 and gray = 255.
Example:
cmsToneCurve* tone;
cmsUInt16Number curve[256];
int i;
cmsHPROFILE hProfile;
for (i = 0; i < 256; i++)
{
curve[i] = (cmsUInt16Number) round(65535.0 * pow(i / 255.0, 2.2));
}
tone = cmsBuildTabulatedToneCurve16(0, 256, curve);
hProfile = cmsCreateGrayProfile(cmsD50_xyY(), tone);
cmsFreeToneCurve(tone);
cmsSaveProfileToFile(hProfile, "gray_test.icc");
cmsCloseProfile(hProfile);
Regards
Marti Maria
The LittleCMS Project
https://www.littlecms.com
> -----Original Message-----
> From: flap <fb...@oh...>
> Sent: Friday, December 29, 2023 2:21 PM
> To: lcm...@li...
> Subject: Re: [Lcms-user] How does a transformation work
>
> Am Freitag, 29. Dezember 2023, 14:01:40 CET schrieb
> mar...@li...:
> > Hi,
> >
> > From your explanation, it seems to me that the transformation you want
> > has
> nothing to do with color management. You
> > know nothing about the L* of your grayscale and need only some
> > scaling. I
> would rather use simple math in this case:
> >
> > Gray_out = (Gray_in * 40) /51 + 40;
> >
> > You could just use a for() loop. This is going to be faster that using
> > any
> color management routines.
>
> Hmm. It just was a test to understand how it (may) works.
> The profile I create is used in the muPDF library to create a greyscale out from
> a PDF document. I would expect, any kind of PDF could be rasterized into a
> greyscale raster this way.
>
> Cheers,
> Jürgen
>
>
>
>
>
> _______________________________________________
> Lcms-user mailing list
> Lcm...@li...
> https://lists.sourceforge.net/lists/listinfo/lcms-user
|
|
From: flap <fb...@oh...> - 2023-12-29 13:21:30
|
Am Freitag, 29. Dezember 2023, 14:01:40 CET schrieb mar...@li...: > Hi, > > From your explanation, it seems to me that the transformation you want has nothing to do with color management. You > know nothing about the L* of your grayscale and need only some scaling. I would rather use simple math in this case: > > Gray_out = (Gray_in * 40) /51 + 40; > > You could just use a for() loop. This is going to be faster that using any color management routines. Hmm. It just was a test to understand how it (may) works. The profile I create is used in the muPDF library to create a greyscale out from a PDF document. I would expect, any kind of PDF could be rasterized into a greyscale raster this way. Cheers, Jürgen |
|
From: flap <fb...@oh...> - 2023-12-29 11:06:08
|
Hi list, what I want: an 8 bit grey-scale output for my printer, where the input dot values (0 … 255) are scaled and limited to values of 40 … 240 (…just an example). So I created a simple test input data (256 elements of unsigned char) with a linear ramp from 0 (at index 0) … 255 (at index 255). And I created an array with 4096 short entries beginning with 40 (* 256 for unsigned short) and ramp up linear to 240 (* 256 for unsigned short) and feed it into cmsBuildTabulatedToneCurve16() and cmsCreateGrayProfile() with cmsD50_xyY() as its whitepoint (for the output profile). For the input profile I used cmsBuildGamma() with a value of 1.0 and cmsCreateGrayProfile() with cmsD50_xyY(). After creating the transformation with cmsCreateTransform() with input/output types both TYPE_GRAY_8 and an intent of INTENT_PERCEPTUAL and applying this transformation with cmsDoTransformLineStride () to my simple input data, the output result is still almost linear from 0 to 255 and not limited to 40 … 240. So, I think I'm using the tone curves in a wrong way. But where is my mistake? Cheers, Jürgen |
|
From: flap <fb...@oh...> - 2023-12-22 10:36:19
|
Hi Marti, Myself wrote: > […] > > I will try with valgrind. Result: classic "use-after-free" error... m( Thank you for pointing me to a memory corruption tip. Cheers, Jürgen |
|
From: <mar...@li...> - 2023-12-22 02:41:43
|
Hi Jürgen, > It only happens (e.g. the error message) in my final application. The same > piece of code works in my test program (which does at most the same, same > PNG file, same output definition). This is memory corruption. Maybe you have closed the input or output profiles before calling cmsCreateTransform? The snipped you send is correct, used in many different places with no problems. Could you run your program under a memory checker, valgrind or visual studio sanitizer, for example? Upgrading to 2.16 would be also a good idea, but I doubt using an old version is the root cause of this issue. Regards Marti Maria The LittleCMS Project https://www.littlecms.com > -----Original Message----- > From: flap <fb...@oh...> > Sent: Thursday, December 21, 2023 6:51 PM > To: lcm...@li... > Subject: [Lcms-user] cmsCreateTransform(): Unclear error message > > Hello list, > > I have the following lines in my code: > > […] > assert(cmsGetColorSpace(info->incms) == cmsSigRgbData); > assert(cmsGetColorSpace(info->outcms) == cmsSigGrayData); > > cmsHTRANSFORM trans = cmsCreateTransform(info->incms, > TYPE_RGB_8, /* from 24 bit RGB raster */ > info->outcms, > TYPE_GRAY_8, /* into an 8 bit grey-scale raster */ > INTENT_PERCEPTUAL, > 0); /* no further flags for now */ > if (trans == NULL) > return -EINVAL; > […] > > The catched error message when calling cmsCreateTransform() is code 13 ('not > suitable') and 'Couldn't link the profiles'. What does it mean? > > It only happens (e.g. the error message) in my final application. The same > piece of code works in my test program (which does at most the same, same > PNG file, same output definition). > > I'm now confused what the difference can be to make the call fail. > > Background: The "info->incms" comes from an embedded ICC profile in the > PNG file and the "info->outcms" is a virtual profile generated with > cmsCreateGrayProfileTHR(). On my system liblcms2.so.2 -> liblcms2.so.2.0.12 > is in use. > > Cheers, > Jürgen > > > > > > _______________________________________________ > Lcms-user mailing list > Lcm...@li... > https://lists.sourceforge.net/lists/listinfo/lcms-user |
|
From: flap <fb...@oh...> - 2023-12-21 22:35:37
|
Hi Marti, mar...@li... wrote: > > It only happens (e.g. the error message) in my final application. The same > > piece of code works in my test program (which does at most the same, same > > PNG file, same output definition). > > This is memory corruption. Maybe you have closed the input or output > profiles before calling cmsCreateTransform? No, both profiles are still open. > The snipped you send is correct, used in many different places with no > problems. Could you run your program under a memory checker, valgrind or > visual studio sanitizer, for example? My programs run with ASAN enabled. Most of the time it triggers in a reliable manner if the memory gets corrupted. Here not - yet. I will try with valgrind. Thanks, Jürgen |
|
From: flap <fb...@oh...> - 2023-12-21 17:51:36
|
Hello list,
I have the following lines in my code:
[…]
assert(cmsGetColorSpace(info->incms) == cmsSigRgbData);
assert(cmsGetColorSpace(info->outcms) == cmsSigGrayData);
cmsHTRANSFORM trans = cmsCreateTransform(info->incms,
TYPE_RGB_8, /* from 24 bit RGB raster */
info->outcms,
TYPE_GRAY_8, /* into an 8 bit grey-scale raster */
INTENT_PERCEPTUAL,
0); /* no further flags for now */
if (trans == NULL)
return -EINVAL;
[…]
The catched error message when calling cmsCreateTransform() is code 13 ('not
suitable') and 'Couldn't link the profiles'. What does it mean?
It only happens (e.g. the error message) in my final application. The same
piece of code works in my test program (which does at most the same, same PNG
file, same output definition).
I'm now confused what the difference can be to make the call fail.
Background: The "info->incms" comes from an embedded ICC profile in the PNG
file and the "info->outcms" is a virtual profile generated with
cmsCreateGrayProfileTHR(). On my system liblcms2.so.2 -> liblcms2.so.2.0.12 is
in use.
Cheers,
Jürgen
|
|
From: <mar...@li...> - 2023-12-04 03:04:08
|
Little CMS 2.16 released I am glad to the announce the release 2.16 of the LittleCMS open-source color engine. lcms2-2.16 is a featured release. Changes: * New: import .CUBE files as RGB device links * New: Read/Write MHC2 tags for Windows GPU access * New: Support for UTF8 on multi-localized Unicode functions * New: Support for OkLab color space, built-in and formatter. * Improved: floating point transforms float -> integers are now honored as float * Improved: MSYS2, mingw is now supported * Improved: preferred CMM, platform and creator now survive profile edition. * Fixed: tificc now can deal with Lab TIFF * Fixed: code can now be compiled by a C++17 compiler, "register" keywork use is detected at compile time. * Fixed: Reverted PostScript creation that corrupted some interpreters. * Bug fixing & security enhancements Little CMS intends to be an open source small-footprint color management engine, with special focus on accuracy and performance. It uses the International Color Consortium standard (ICC), which is the modern standard when regarding to color management. The ICC specification is widely used and is referred to in many International and other de-facto standards. It was approved as an International Standard, ISO 15076-1, in 2005. Main site: http://www.littlecms.com Downloads: http://www.littlecms.com/download.html https://sourceforge.net/projects/lcms/files/latest/download https://github.com/mm2/Little-CMS/releases/tag/lcms2.16 Best regards, Marti Maria The Little CMS project http://www.littlecms.com |
|
From: <mar...@li...> - 2023-11-19 15:03:45
|
Hi, It's time to make a new release. I try to alternate stabilization and new features, and this time it's new features. The first release candidate is available here: https://github.com/mm2/Little-CMS/releases/tag/lcms2.16rc1 Changes * New: import .CUBE files as RGB devicelinks * New: Read/Write MHC2 tags for Windows GPU access * New: Support for UTF8 on multilocalized unicode functions * New: Support for OkLab color space, built-in and formatter. * Improved: floating point transforms float -> integers are now honored as float * Improved: MSYS2, mingw is now supported * Improved: preferred CMM, platform and creator now survive profile edition. * Fixed: tificc now can deal with Lab TIFF * Fixed: code can now be compiled by a C++17 compiler, "register" keywork use detected at compile time. * Fixed: Reverted PostScript creation that corrupted some interpreters. * Bug fixing & security enhancements Feel free to test it on all your products, tentative release date for final lcms2-2.16 is end of Nov-2023 Please contact me on any issue either on info { at } littecms.com or using this list. Best regards Marti Maria The LittleCMS Project https://www.littlecms.com |
|
From: <mar...@li...> - 2023-08-15 11:57:59
|
Hello Sergey, > The actual data of the image(byte, short, int, float, double)->float->short->start > lcms > internal->float->apply color transform in floats->end lcms > internal->float->internals->short->float->the data of the > image(byte, short, int, float, double). So at the end we have a "good" precision > of the result especially if the image stores the color component in 17+ bits. I don't know the internal architecture of OpenJDK, so maybe this is not feasible, but it seems to me the way you are doing the conversions is a serious throughput killer. Lcms goes in a lot of trouble to optimize color transforms to make them as fast as possible whilst keeping the maximum precision. So, if you are going to convert a bitmap of 8 bits to another bitmap of 8 bits, your best option is to tell lcms to use 8 bits on input and output. The math precision and throughput performance you will obtain is actually better than going to float and then back to 8 bits, because lcms use tricks on rounding and fixed-point interpolation to go fast and accurate. Ditto for 16 bits, float, double, half... Floating point transforms should be only used when your data is already in floating point, or in the case you want to convert to floating point. But that should be transparent to you, you should only tell the engine how your data is organized and let it to pick the better way to do the conversion. If you always convert to float assuming this is going to increase precision you are obtaining the inverse effect: sometimes less precision and definitively slower throughput. But again, I don't know OpenJDK architecture, so maybe the float step is unavoidable because other components. Best regards Marti Maria The LittleCMS Project https://www.littlecms.com > -----Original Message----- > From: Sergey Bylokhov <byl...@am...> > Sent: Monday, August 14, 2023 10:18 PM > To: Philip Race <phi...@or...>; mar...@li...; lcms- > us...@li... > Subject: Re: [Lcms-user] Configuration of the bounded/unbounded mode > > On 8/13/23 15:07, Philip Race wrote: > > Sergey, > > > > Why do you want to do this ? I'm not sure I see the value in it. > > > > Although JDK does support float for images, none of the standard image > > formats use floats. > > Unfortunately not, even though most standard images use bytes and ints to > convert color profiles and access pixels in images, we use floats. So the > common pattern we have is: > The actual data of the image(byte, short, int, float, double)->float->short->start > lcms > internal->float->apply color transform in floats->end lcms > internal->float->internals->short->float->the data of the > image(byte, short, int, float, double). So at the end we have a "good" precision > of the result especially if the image stores the color component in 17+ bits. > > An examples of such conversion: > 1. > https://github.com/openjdk/jdk/blob/595fdd36c5f735b53ed2950c539be46382f > 9bcdd/src/java.desktop/share/classes/sun/java2d/cmm/lcms/LCMSTransform.j > ava#L230 > 2. > https://github.com/openjdk/jdk/blob/595fdd36c5f735b53ed2950c539be46382f > 9bcdd/src/java.desktop/share/classes/java/awt/image/ColorConvertOp.java#L8 > 09 > 3. Well we have a public API for such float based conversion - > to/From/RGB/CIEXYZ: > https://github.com/openjdk/jdk/blob/595fdd36c5f735b53ed2950c539be46382f > 9bcdd/src/java.desktop/share/classes/java/awt/color/ICC_ColorSpace.java#L20 > 2 > > > But there are a few things I would like to check before starting to work on the > OpenJDK side. > 1. The slow performance of the float based calculations, described here: > https://github.com/mm2/Little-CMS/issues/356 But I think elimination of an > additional conversion should compensate that. > 2. Compatibility related to the out-gamut values discussed in this thread. I > would like to understand how to implement clip properly. Note that our > current implementation do not clip out-of-gamtut values but blindly cast to > short and get some "random" value at the end. > > -- > Best regards, Sergey. |
|
From: Sergey B. <byl...@am...> - 2023-08-14 20:18:06
|
On 8/13/23 15:07, Philip Race wrote: > Sergey, > > Why do you want to do this ? I'm not sure I see the value in it. > > Although JDK does support float for images, none of the standard image > formats use floats. Unfortunately not, even though most standard images use bytes and ints to convert color profiles and access pixels in images, we use floats. So the common pattern we have is: The actual data of the image(byte, short, int, float, double)->float->short->start lcms internal->float->apply color transform in floats->end lcms internals->short->float->the data of the image(byte, short, int, float, double). So at the end we have a "good" precision of the result especially if the image stores the color component in 17+ bits. An examples of such conversion: 1. https://github.com/openjdk/jdk/blob/595fdd36c5f735b53ed2950c539be46382f9bcdd/src/java.desktop/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java#L230 2. https://github.com/openjdk/jdk/blob/595fdd36c5f735b53ed2950c539be46382f9bcdd/src/java.desktop/share/classes/java/awt/image/ColorConvertOp.java#L809 3. Well we have a public API for such float based conversion - to/From/RGB/CIEXYZ: https://github.com/openjdk/jdk/blob/595fdd36c5f735b53ed2950c539be46382f9bcdd/src/java.desktop/share/classes/java/awt/color/ICC_ColorSpace.java#L202 But there are a few things I would like to check before starting to work on the OpenJDK side. 1. The slow performance of the float based calculations, described here: https://github.com/mm2/Little-CMS/issues/356 But I think elimination of an additional conversion should compensate that. 2. Compatibility related to the out-gamut values discussed in this thread. I would like to understand how to implement clip properly. Note that our current implementation do not clip out-of-gamtut values but blindly cast to short and get some "random" value at the end. -- Best regards, Sergey. |
|
From: Philip R. <phi...@or...> - 2023-08-13 22:19:26
|
Sergey, Why do you want to do this ? I'm not sure I see the value in it. Although JDK does support float for images, none of the standard image formats use floats. So I'm not sure how well this change would be tested nor where we'd see any benefit from it so who is asking for this ? -phil. On 8/13/23 2:36 AM, mar...@li... wrote: > Hi, > > Keep in mind the CMM internally operates always in unbounded mode and clips > values at final stage if you use anything but floating point. Also, not all > profiles allow unbounded mode. Doing the change you purpose would have a > severe impact on applications not expecting values negative or over 1.0. > By using shorts, you are limiting precision to 16 bits, if you use floats, > you get more accuracy. Also note the encoding range changes, 0.1 for RGB, > 0.100 for CMYK and for Lab it comes already decoded. > Unbounded mode works in both directions, if you feed the transform with a > value bigger then 1.0 and the profile supports it, the obtained XYZ would be > an out-of-gamut extrapolation. > > The flag cmsFLAGS_NONEGATIVES was introduced to prevent only negative values > because security issues, does not work for values bigger than 1. In any > case, no matter what you do, the result would be wrong because this is an > out of gamut value. Clipping is an option, just the simplest gamut mapping > you could do. > >> 3. What about the use case when the user splits the "big" transform into a >> few small intermediate transformations, is it possible to enable > "unbounded" >> mode for all transformations except for the output of the latest > transform? > > Sure. Just ad a couple of "if >= 0 && <= 1.0" at the very end of the > pipeline. > > Regards > > Marti Maria > The LittleCMS Project > https://www.littlecms.com > > > >> -----Original Message----- >> From: Sergey Bylokhov via Lcms-user <lcm...@li...> >> Sent: Sunday, August 13, 2023 1:48 AM >> To: lcm...@li... >> Subject: [Lcms-user] Configuration of the bounded/unbounded mode >> >> Hello, Colors Experts! >> >> I am working on the OpenJDK project and have a couple of questions about >> the LittleCMS library. >> >> The OpenJDK uses the LittleCMS for color conversion for a long time. And > one >> of the use cases is getting the pixel data from the user in float format. >> Unfortunately before passing this float data to the LittleCMS the OpenJDK >> converts them to shorts(16 bit) and after color transformation converts > the >> shorts to floats back and returns that floats to the user. >> >> The current implementation was done for LittleCMS 1 and was not updated > for >> version 2. I have read this[1] document about the "Floating Point Encoding >> Range" added to the spec in 2006 and how it is implemented in the > LittleCMS >> library and would like to use this functionality in OpenJDK. >> >> The change in OpenJDK should be straightforward, delete the intermediate >> conversion from floats to shorts and back and pass the floats directly to > the >> LittleCMS library. But this is a moment I would like to clarify some > possible >> impacts on the compatibility with the old behavior. >> >> 1. It is a good thing to do all intermediate computation in the unbounded >> mode during color transformation, but how the out-of-gamut values are >> handled for input and output data? That was not a problem for short but >> could be a problem for floats, for example, what will happen if 2.0f is > passed >> as a color value for the sRGB format - will it be clipped? or error will > occur? or >> transformation will be applied as-is? >> >> 2. What about the output? There is a cmsFLAGS_NONEGATIVES flag to prevent >> negative values but when and how that values will be clipped by the upper >> bounds? There are no options to configure that and it seems some clipping >> occurs here and there in the code based on some constants which are not >> exposed as CMS API. >> >> 3. What about the use case when the user splits the "big" transform into a >> few small intermediate transformations, is it possible to enable > "unbounded" >> mode for all transformations except for the output of the latest > transform? >> Thank you for any suggestions! >> >> [1] https://www.littlecms.com/CIC18_UnboundedCMM.pdf >> >> -- >> Best regards, Sergey. >> >> >> _______________________________________________ >> Lcms-user mailing list >> Lcm...@li... >> https://lists.sourceforge.net/lists/listinfo/lcms-user > > > _______________________________________________ > Lcms-user mailing list > Lcm...@li... > https://lists.sourceforge.net/lists/listinfo/lcms-user |
|
From: <mar...@li...> - 2023-08-13 10:53:20
|
Hi, Keep in mind the CMM internally operates always in unbounded mode and clips values at final stage if you use anything but floating point. Also, not all profiles allow unbounded mode. Doing the change you purpose would have a severe impact on applications not expecting values negative or over 1.0. By using shorts, you are limiting precision to 16 bits, if you use floats, you get more accuracy. Also note the encoding range changes, 0.1 for RGB, 0.100 for CMYK and for Lab it comes already decoded. Unbounded mode works in both directions, if you feed the transform with a value bigger then 1.0 and the profile supports it, the obtained XYZ would be an out-of-gamut extrapolation. The flag cmsFLAGS_NONEGATIVES was introduced to prevent only negative values because security issues, does not work for values bigger than 1. In any case, no matter what you do, the result would be wrong because this is an out of gamut value. Clipping is an option, just the simplest gamut mapping you could do. > 3. What about the use case when the user splits the "big" transform into a > few small intermediate transformations, is it possible to enable "unbounded" > mode for all transformations except for the output of the latest transform? Sure. Just ad a couple of "if >= 0 && <= 1.0" at the very end of the pipeline. Regards Marti Maria The LittleCMS Project https://www.littlecms.com > -----Original Message----- > From: Sergey Bylokhov via Lcms-user <lcm...@li...> > Sent: Sunday, August 13, 2023 1:48 AM > To: lcm...@li... > Subject: [Lcms-user] Configuration of the bounded/unbounded mode > > Hello, Colors Experts! > > I am working on the OpenJDK project and have a couple of questions about > the LittleCMS library. > > The OpenJDK uses the LittleCMS for color conversion for a long time. And one > of the use cases is getting the pixel data from the user in float format. > Unfortunately before passing this float data to the LittleCMS the OpenJDK > converts them to shorts(16 bit) and after color transformation converts the > shorts to floats back and returns that floats to the user. > > The current implementation was done for LittleCMS 1 and was not updated for > version 2. I have read this[1] document about the "Floating Point Encoding > Range" added to the spec in 2006 and how it is implemented in the LittleCMS > library and would like to use this functionality in OpenJDK. > > The change in OpenJDK should be straightforward, delete the intermediate > conversion from floats to shorts and back and pass the floats directly to the > LittleCMS library. But this is a moment I would like to clarify some possible > impacts on the compatibility with the old behavior. > > 1. It is a good thing to do all intermediate computation in the unbounded > mode during color transformation, but how the out-of-gamut values are > handled for input and output data? That was not a problem for short but > could be a problem for floats, for example, what will happen if 2.0f is passed > as a color value for the sRGB format - will it be clipped? or error will occur? or > transformation will be applied as-is? > > 2. What about the output? There is a cmsFLAGS_NONEGATIVES flag to prevent > negative values but when and how that values will be clipped by the upper > bounds? There are no options to configure that and it seems some clipping > occurs here and there in the code based on some constants which are not > exposed as CMS API. > > 3. What about the use case when the user splits the "big" transform into a > few small intermediate transformations, is it possible to enable "unbounded" > mode for all transformations except for the output of the latest transform? > > Thank you for any suggestions! > > [1] https://www.littlecms.com/CIC18_UnboundedCMM.pdf > > -- > Best regards, Sergey. > > > _______________________________________________ > Lcms-user mailing list > Lcm...@li... > https://lists.sourceforge.net/lists/listinfo/lcms-user |