Hi,
I believe I've found a bug in LittleCMS. Either it's a bug or I'm very confused
about the formatters. I've looked around quite a bit in the mailing list and
haven't seen this reported. This appears in version 2.6.
It happens if you use floating point components with a leading extra field.
Everything was working fine until I color converted some floating point ARGB
pixels. The result ended up with a "squished" output which looked like
LittleCMS thought the pixels were three components long rather than four. After
walking through it in the debugger I ended up in the PackFloatsFromFloat
routine.
I hope the code indentation survives. I'm new to mailing lists. (crosses
fingers) May the Gods of indentation smile upon me...
The code in PackFloatsFromFloat (cmspack.c) looks like this:
if (ExtraFirst)
start = Extra;
for (i=0; i < nChan; i++) {
int index = DoSwap ? (nChan - i - 1) : i;
v = wOut[index] * maximum;
if (Reverse)
v = maximum - v;
if (Planar)
((cmsFloat32Number*) output)[(i + start)* Stride]=
(cmsFloat32Number) v;
else
((cmsFloat32Number*) output)[i + start] = (cmsFloat32Number) v;
}
if (!ExtraFirst) {
output += Extra * sizeof(cmsFloat32Number);
}
if (Extra == 0 && SwapFirst) {
memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat32Number));
*swap1 = (cmsFloat32Number) v;
}
if (T_PLANAR(info -> OutputFormat))
return output + sizeof(cmsFloat32Number);
else
return output + nChan * sizeof(cmsFloat32Number);
In my case ExtraFirst is TRUE and Extra is 1 because of the leading alpha and
it packs the pixel properly. The problem is that the function is supposed to
return the output address kicked past the entire pixel but it only kicks past
three components rather than four.
return output + nChan * sizeof(cmsFloat32Number);
The output pointer is only kicked past trailing extra fields and not leading
ones. If !ExtraFirst then the return statement above works fine because of this:
if (!ExtraFirst) {
output += Extra * sizeof(cmsFloat32Number);
}
But that doesn't work for ExtraFirst==TRUE. In that case it returns output
kicked past only nChan components.
I don't use planar pixels but I think that the code just above is also wrong
for planar pixels which should always return output + sizeof(cmsFloat32Number)
independent of whether there are extra fields or not. At least that what it
looks like to me. I don't use planar pixels. At least not in the last twenty
years anyway.
This is my "fixed" version of the code:
if (ExtraFirst)
start = Extra;
for (i=0; i < nChan; i++) {
int index = DoSwap ? (nChan - i - 1) : i;
v = wOut[index] * maximum;
if (Reverse)
v = maximum - v;
if (Planar)
((cmsFloat32Number*) output)[(i + start)* Stride]=
(cmsFloat32Number) v;
else
((cmsFloat32Number*) output)[i + start] = (cmsFloat32Number) v;
}
#if FIXIT==0
if (!ExtraFirst) {
output += Extra * sizeof(cmsFloat32Number);
}
#endif
if (Extra == 0 && SwapFirst) {
memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat32Number));
*swap1 = (cmsFloat32Number) v;
}
if (T_PLANAR(info -> OutputFormat))
return output + sizeof(cmsFloat32Number);
else
#if FIXIT==0
return output + nChan * sizeof(cmsFloat32Number);
#else
return output + (nChan + Extra) * sizeof(cmsFloat32Number);
#endif
I don't know LittleCMS at all well but I've found this kind of code in six
places:
PackFloatFrom16
PackFloatsFromFloat
PackDoubleFrom16
PackDoublesFromFloat
PackHalfFrom16
PackHalfFromFloat
I believe this fixes the problem for both planar pixels and packed ones. But
I'm definitely not a LittleCMS expert. I'd double and triple check me. But this
has worked for me so far. Thanks for your time.
Mark Allen
playtool.com
------------------------------------------------------------------------------
Open source business process management suite built on Java and Eclipse
Turn processes into business applications with Bonita BPM Community Edition
Quickly connect people, data, and systems into organized workflows
Winner of BOSSIE, CODIE, OW2 and Gartner awards
http://p.sf.net/sfu/Bonitasoft
_______________________________________________
Lcms-user mailing list
Lcms-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lcms-user