After taking a look, it seems to me it is not a bug on the lcms library but in your code. If you examine the documentation, in the API reference of "cmsReadTag", is stated that:
"The memory belongs to the profile and is set free on closing the profile."
This means: anything coming from cmsReadTag should be treated as const. Otherwise, you are modifying structures that are owned by the profile, when the profile is set free, it tries to free those structures. If you have modified the internal pointers, it can get corrupted.
The obvious solution is to dup' the pipeline after reading it. This guarantees the copy of pipeline is not owned by the profile but by you, and you are free to modify anything because nobody else keeps pointers to it.
For linked tags, think the linked tag is just an alias that points to a real tag. If you modify the real tag, the alias would point to the modified tag as well, if you modify the alias, then it will be no longer an alias but a real tag. You can check whatever a tag is an alias by using the function cmsIsLinkedTag(). The syntax is cmsIsLinkedTag(<alias>) --> real tag.
I've added a test in the testbed to double check this case.
I extracted the code from our library, and removed nearly all calls besides the ones to lcms2
What the code does now (because most of the useful code is gone), is to
- open the profile
- load the tag
- 'resize' the CLUT in the pipeline to 3 dimensions, 33 samples per dimension, 3 output channels
- save this tag again in the profile
- save the profile
I did not really try to compile this code, but these are indeed all the calls made to lcms2
cmsWriteTag(_profile.GetLCMS2Profile(), lcms2::ProfileEditingSignatureToLCMSSignature(_signature), sizedpipeline);
// (over)writing the tag will also free the 'old' pipe line, so we do not have to free the old
// pipeline. But .... writing the tag will also store only a copy of our new pipeline, so we
// have to free our pipeline
I am using lcms2 to update profile (pipe-lines) In general this works fine,
but the profiles become corrupt when they have linked tags.
I open a profile that has linked tags for A2B1 and A2B2.
I see in the internal structures that all data is correctly read, both tags
shared the same pointer, offset etc, and A2B2 is marked as a link to A2B1 I
then create a new pipeline, and call writetag on it to store in in A2B1
(this appears the be the only way to update the CLUT data in a pipeline)
however, when I follow the code in writetag, then I do not see any change to
the A2B2 data. e.g. the offset and pointer are not reset, neither are they
linked to the new data. I am not sure what the correct behavior would be,
but something is wrong here.
I can also not 'relink' with linktag because that one complains about the
fact that the A2B2 tag already exists...