summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarti <marti.maria@tktbrainpower.com>2016-06-08 08:13:55 +0200
committerMarti <marti.maria@tktbrainpower.com>2016-06-08 08:13:55 +0200
commita47e96ca6539d8165c453a61a19597de56bad246 (patch)
treefd5c04a248fcd818ed1371a4259b6c17617efd32
parentefc9630f37e35f9ced3e4e59090e2dec3e63db80 (diff)
downloadlcms2-a47e96ca6539d8165c453a61a19597de56bad246.tar.gz
Changes from Noel Carboni regarding copy alpha
-rw-r--r--AUTHORS1
-rw-r--r--src/cmsalpha.c153
2 files changed, 96 insertions, 58 deletions
diff --git a/AUTHORS b/AUTHORS
index 5ad2e84..147246a 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -36,6 +36,7 @@ Christopher James Halse Rogers
John Hein
Thomas Weber (Debian)
Mark Allen
+Noel Carboni
Special Thanks
--------------
diff --git a/src/cmsalpha.c b/src/cmsalpha.c
index 904ce71..7d6aa34 100644
--- a/src/cmsalpha.c
+++ b/src/cmsalpha.c
@@ -408,74 +408,111 @@ void ComputeComponentIncrements(cmsUInt32Number Format,
// Handles extra channels copying alpha if requested by the flags
void _cmsHandleExtraChannels(_cmsTRANSFORM* p, const void* in,
- void* out,
- cmsUInt32Number PixelsPerLine,
- cmsUInt32Number LineCount,
- const cmsStride* Stride)
-{
- size_t i, j, k;
- cmsUInt32Number nExtra;
- cmsUInt32Number SourceStartingOrder[cmsMAXCHANNELS];
- cmsUInt32Number SourceIncrements[cmsMAXCHANNELS];
- cmsUInt32Number DestStartingOrder[cmsMAXCHANNELS];
- cmsUInt32Number DestIncrements[cmsMAXCHANNELS];
- cmsUInt32Number SourceStrideIncrements[cmsMAXCHANNELS];
- cmsUInt32Number DestStrideIncrements[cmsMAXCHANNELS];
-
- cmsUInt8Number* SourcePtr[cmsMAXCHANNELS];
- cmsUInt8Number* DestPtr[cmsMAXCHANNELS];
-
- cmsFormatterAlphaFn copyValueFn;
-
- // Make sure we need some copy
- if (!(p->dwOriginalFlags & cmsFLAGS_COPY_ALPHA))
- return;
-
- // Make sure we have same number of alpha channels. If not, just return as this should be checked at transform creation time.
- nExtra = T_EXTRA(p->InputFormat);
- if (nExtra != T_EXTRA(p->OutputFormat))
- return;
-
- // Anything to do?
- if (nExtra == 0)
- return;
+ void* out,
+ cmsUInt32Number PixelsPerLine,
+ cmsUInt32Number LineCount,
+ const cmsStride* Stride)
+{
+ cmsUInt32Number i, j, k;
+ cmsUInt32Number nExtra;
+ cmsUInt32Number SourceStartingOrder[cmsMAXCHANNELS];
+ cmsUInt32Number SourceIncrements[cmsMAXCHANNELS];
+ cmsUInt32Number DestStartingOrder[cmsMAXCHANNELS];
+ cmsUInt32Number DestIncrements[cmsMAXCHANNELS];
- // Compute the increments
- ComputeComponentIncrements(p->InputFormat, Stride->BytesPerPlaneIn, SourceStartingOrder, SourceIncrements);
- ComputeComponentIncrements(p->OutputFormat, Stride->BytesPerPlaneOut, DestStartingOrder, DestIncrements);
-
- // Check for conversions 8, 16, half, float, dbl
- copyValueFn = _cmsGetFormatterAlpha(p->ContextID, p->InputFormat, p->OutputFormat);
+ cmsFormatterAlphaFn copyValueFn;
- memset(SourceStrideIncrements, 0, sizeof(SourceStrideIncrements));
- memset(DestStrideIncrements, 0, sizeof(DestStrideIncrements));
+ // Make sure we need some copy
+ if (!(p->dwOriginalFlags & cmsFLAGS_COPY_ALPHA))
+ return;
- // The loop itself
- for (i = 0; i < LineCount; i++) {
+ // Exit early if in-place color-management is occurring - no need to copy extra channels to themselves.
+ if (p->InputFormat == p->OutputFormat && in == out)
+ return;
- // Prepare pointers for the loop
- for (j = 0; j < nExtra; j++) {
+ // Make sure we have same number of alpha channels. If not, just return as this should be checked at transform creation time.
+ nExtra = T_EXTRA(p->InputFormat);
+ if (nExtra != T_EXTRA(p->OutputFormat))
+ return;
- SourcePtr[j] = (cmsUInt8Number*)in + SourceStartingOrder[j] + SourceStrideIncrements[j];
- DestPtr[j] = (cmsUInt8Number*)out + DestStartingOrder[j] + DestStrideIncrements[j];
- }
+ // Anything to do?
+ if (nExtra == 0)
+ return;
- for (j = 0; j < PixelsPerLine; j++) {
+ // Compute the increments
+ ComputeComponentIncrements(p->InputFormat, Stride->BytesPerPlaneIn, SourceStartingOrder, SourceIncrements);
+ ComputeComponentIncrements(p->OutputFormat, Stride->BytesPerPlaneOut, DestStartingOrder, DestIncrements);
- for (k = 0; k < nExtra; k++) {
+ // Check for conversions 8, 16, half, float, dbl
+ copyValueFn = _cmsGetFormatterAlpha(p->ContextID, p->InputFormat, p->OutputFormat);
- copyValueFn(DestPtr[k], SourcePtr[k]);
+ if (nExtra == 1) { // Optimized routine for copying a single extra channel quickly
- SourcePtr[k] += SourceIncrements[k];
- DestPtr[k] += DestIncrements[k];
- }
- }
+ cmsUInt8Number* SourcePtr;
+ cmsUInt8Number* DestPtr;
- for (j = 0; j < nExtra; j++) {
+ cmsUInt32Number SourceStrideIncrement = 0;
+ cmsUInt32Number DestStrideIncrement = 0;
- SourceStrideIncrements[j] += Stride->BytesPerLineIn;
- DestStrideIncrements[j] += Stride->BytesPerLineOut;
- }
- }
+ // The loop itself
+ for (i = 0; i < LineCount; i++) {
+
+ // Prepare pointers for the loop
+ SourcePtr = (cmsUInt8Number*)in + SourceStartingOrder[0] + SourceStrideIncrement;
+ DestPtr = (cmsUInt8Number*)out + DestStartingOrder[0] + DestStrideIncrement;
+
+ for (j = 0; j < PixelsPerLine; j++) {
+
+ copyValueFn(DestPtr, SourcePtr);
+
+ SourcePtr += SourceIncrements[0];
+ DestPtr += DestIncrements[0];
+ }
+
+ SourceStrideIncrement += Stride->BytesPerLineIn;
+ DestStrideIncrement += Stride->BytesPerLineOut;
+ }
+
+ }
+ else { // General case with more than one extra channel
+
+ cmsUInt8Number* SourcePtr[cmsMAXCHANNELS];
+ cmsUInt8Number* DestPtr[cmsMAXCHANNELS];
+
+ cmsUInt32Number SourceStrideIncrements[cmsMAXCHANNELS];
+ cmsUInt32Number DestStrideIncrements[cmsMAXCHANNELS];
+
+ memset(SourceStrideIncrements, 0, sizeof(SourceStrideIncrements));
+ memset(DestStrideIncrements, 0, sizeof(DestStrideIncrements));
+
+ // The loop itself
+ for (i = 0; i < LineCount; i++) {
+
+ // Prepare pointers for the loop
+ for (j = 0; j < nExtra; j++) {
+
+ SourcePtr[j] = (cmsUInt8Number*)in + SourceStartingOrder[j] + SourceStrideIncrements[j];
+ DestPtr[j] = (cmsUInt8Number*)out + DestStartingOrder[j] + DestStrideIncrements[j];
+ }
+
+ for (j = 0; j < PixelsPerLine; j++) {
+
+ for (k = 0; k < nExtra; k++) {
+
+ copyValueFn(DestPtr[k], SourcePtr[k]);
+
+ SourcePtr[k] += SourceIncrements[k];
+ DestPtr[k] += DestIncrements[k];
+ }
+ }
+
+ for (j = 0; j < nExtra; j++) {
+
+ SourceStrideIncrements[j] += Stride->BytesPerLineIn;
+ DestStrideIncrements[j] += Stride->BytesPerLineOut;
+ }
+ }
+ }
}
+