Hi Frank,

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.

You code does something like:

Pipeline = cmsReadTag().
..Modify Pipeline..
cmsWriteTag(pipeline)
cmsPipelineFree (pipeline)

And should do:

Pipeline = cmsReadTag().
Newpipeline = cmsPipelineDup(pipeline)
..Modify newpipeline..
cmsWriteTag(newpipeline)
cmsPipelineFree(newpipeline)

Does it make sense?

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.

Best regards
Marti




From: Frank Vyncke [mailto:frank.vyn...@yin4yang.com]
Sent: lunes, 30 de julio de 2012 16:32
To: Marti Maria
Cc: lcms-user@lists.sourceforge.net
Subject: Re: [Lcms-user] profile corrupt after update

Marti,

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

-------------- begin snippet ------------------------
                                FILE * loadFrom = gmg::fopen(_path, "rb");
                                cmsProfile profile = 
cmsOpenProfileFromStream(loadFrom, "r");

                                cmsPipeline * pipeline = reinterpret_cast< 
cmsPipeline * >(cmsReadTag(profile, cmsSigAToB1Tag));
                                if (pipeline == NULL)
                                {
                                                return false;
                                }

                                for (cmsStage* stage = 
cmsPipelineGetPtrToFirstStage(pipeline); stage != NULL; stage = 
cmsPipelineGetPtrToFirstStage(pipeline))
                                {
                                                cmsStageSignature 
stageSignature = cmsStageType(stage);
                                                if (stageSignature == 
cmsSigCLutElemType)
                                                {
                                                                // delete stage 
from pipe line
                                                                
cmsPipelineUnlinkStage(_pipeline, cmsAT_BEGIN, NULL);

                                                                // and create 
the one with the size we want
                                                                std::vector< 
cmsUInt32Number > lcmsGranularity(3, 33);

                                                                stage = 
cmsStageAllocCLut16bitGranular(contextID, &lcmsGranularity[0], 
granularity.size(), 3, NULL);
                                                }
                                                else
                                                {
                                                                // extract 
stage from pipe line
                                                                
cmsPipelineUnlinkStage(_pipeline, cmsAT_BEGIN, &stage);
                                                }

                                                
cmsPipelineInsertStage(updatedPipeline, cmsAT_END, stage);
                                }

                                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
                                cmsPipelineFree(sizedpipeline);

                                FILE * saveTo = gmg::fopen(savePath, "wb");
                                bool success = 
cmsSaveProfileToStream(cmsProfile, saveTo) == TRUE;
                                cmsCloseProfile(cmsProfile);

-------------- end snippet ------------------------

After running this kind of code on a profile with linked tags, the profile is 
corrupt after write

Regards,
Frank
On 30 Jul 2012, at 16:14, Marti Maria wrote:


Hi Frank,

Do you mean you are trying to edit a profile which already have linked tags,
and then you try to rewrite one of the copies?

It may be a bug... Do you have code that illustrates the issue?
Thanks,
Marti


-----Original Message-----
From: Frank Vyncke 
[mailto:frank.vyn...@yin4yang.com]<mailto:[mailto:frank.vyn...@yin4yang.com]>
Sent: lunes, 30 de julio de 2012 14:50
To: lcms-user@lists.sourceforge.net<mailto:lcms-user@lists.sourceforge.net>
Subject: [Lcms-user] profile corrupt after update

Hi,

I am using lcms2 to update profile (pipe-lines) In general this works fine,
but the profiles become corrupt when they have linked tags.

steps:
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...

Any idea?

Frank
----------------------------------------------------------------------------
--
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and threat
landscape has changed and how IT managers can respond. Discussions will
include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Lcms-user mailing list
Lcms-user@lists.sourceforge.net<mailto:Lcms-user@lists.sourceforge.net>
https://lists.sourceforge.net/lists/listinfo/lcms-user

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Lcms-user mailing list
Lcms-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lcms-user

Reply via email to