diff options
author | Robin Watts <robin.watts@artifex.com> | 2018-11-28 19:13:16 +0000 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2018-11-28 19:44:32 +0000 |
commit | 8d462b070127d3541402b4fda670e0b20c6a61a4 (patch) | |
tree | 3099a572b8e25f252e270f0d0f7f33ccfcee63f3 /lcms2mt | |
parent | 87ec442bc2b0bfa6607c5fb7d085dd85f24e1416 (diff) | |
download | ghostpdl-8d462b070127d3541402b4fda670e0b20c6a61a4.tar.gz |
LCMS2MT: Planar data fix.
The PrecalculatedXFORMIdentity case was failing to allow for planar
data. Fix that here.
Also, optimise the src = dst case.
Diffstat (limited to 'lcms2mt')
-rw-r--r-- | lcms2mt/src/cmsxform.c | 71 |
1 files changed, 63 insertions, 8 deletions
diff --git a/lcms2mt/src/cmsxform.c b/lcms2mt/src/cmsxform.c index e80cc6dc8..bcc9c623f 100644 --- a/lcms2mt/src/cmsxform.c +++ b/lcms2mt/src/cmsxform.c @@ -390,26 +390,74 @@ void PrecalculatedXFORMIdentity(cmsContext ContextID, cmsUInt32Number LineCount, const cmsStride* Stride) { + cmsUInt32Number bpli = Stride->BytesPerLineIn; + cmsUInt32Number bplo = Stride->BytesPerLineOut; + int bpp; + cmsUNUSED_PARAMETER(ContextID); + + /* Silence some warnings */ + (void)bpli; + (void)bplo; + + if ((in == out && bpli == bplo) || PixelsPerLine == 0) + return; + + bpp = T_BYTES(p->InputFormat); + if (bpp == 0) + bpp = sizeof(double); + bpp *= T_CHANNELS(p->InputFormat) + T_EXTRA(p->InputFormat); + PixelsPerLine *= bpp; /* Convert to BytesPerLine */ + while (LineCount-- > 0) + { + memmove(out, in, PixelsPerLine); + in = (void *)((cmsUInt8Number *)in + bpli); + out = (void *)((cmsUInt8Number *)out + bplo); + } +} + +static +void PrecalculatedXFORMIdentityPlanar(cmsContext ContextID, + _cmsTRANSFORM* p, + const void* in, + void* out, + cmsUInt32Number PixelsPerLine, + cmsUInt32Number LineCount, + const cmsStride* Stride) +{ + cmsUInt32Number bpli = Stride->BytesPerLineIn; + cmsUInt32Number bplo = Stride->BytesPerLineOut; cmsUInt32Number bppi = Stride->BytesPerPlaneIn; cmsUInt32Number bppo = Stride->BytesPerPlaneOut; int bpp; + int planes; + const void *plane_in; + void *plane_out; cmsUNUSED_PARAMETER(ContextID); /* Silence some warnings */ + (void)bpli; + (void)bplo; (void)bppi; (void)bppo; - if (PixelsPerLine == 0) + if ((in == out && bpli == bplo && bppi == bppo) || PixelsPerLine == 0) return; bpp = T_BYTES(p->InputFormat); if (bpp == 0) bpp = sizeof(double); - bpp *= T_CHANNELS(p->InputFormat) + T_EXTRA(p->InputFormat); PixelsPerLine *= bpp; /* Convert to BytesPerLine */ - while (LineCount-- > 0) + planes = T_CHANNELS(p->InputFormat) + T_EXTRA(p->InputFormat); + while (planes-- > 0) { - memcpy(out, in, PixelsPerLine); + plane_in = in; + plane_out = out; + while (LineCount-- > 0) + { + memmove(plane_out, plane_in, PixelsPerLine); + plane_in = (void *)((cmsUInt8Number *)plane_in + bpli); + plane_out = (void *)((cmsUInt8Number *)plane_out + bplo); + } in = (void *)((cmsUInt8Number *)in + bppi); out = (void *)((cmsUInt8Number *)out + bppo); } @@ -961,9 +1009,12 @@ _cmsFindFormatter(_cmsTRANSFORM* p, cmsUInt32Number InputFormat, cmsUInt32Number if (dwFlags & cmsFLAGS_GAMUTCHECK) p ->xform = PrecalculatedXFORMGamutCheck; // Gamut check, no cache else if ((InputFormat & ~COLORSPACE_SH(31)) == (OutputFormat & ~COLORSPACE_SH(31)) && - _cmsLutIsIdentity(p->core->Lut)) - p ->xform = PrecalculatedXFORMIdentity; - else + _cmsLutIsIdentity(p->core->Lut)) { + if (T_PLANAR(InputFormat)) + p ->xform = PrecalculatedXFORMIdentityPlanar; + else + p ->xform = PrecalculatedXFORMIdentity; + } else p ->xform = PrecalculatedXFORM; // No cache, no gamut check return; } @@ -973,7 +1024,11 @@ _cmsFindFormatter(_cmsTRANSFORM* p, cmsUInt32Number InputFormat, cmsUInt32Number } if ((InputFormat & ~COLORSPACE_SH(31)) == (OutputFormat & ~COLORSPACE_SH(31)) && _cmsLutIsIdentity(p->core->Lut)) { - p ->xform = PrecalculatedXFORMIdentity; /* No point in a cache here! */ + /* No point in a cache here! */ + if (T_PLANAR(InputFormat)) + p ->xform = PrecalculatedXFORMIdentityPlanar; + else + p ->xform = PrecalculatedXFORMIdentity; return; } if (T_EXTRA(InputFormat) != 0) { |