//---------------------------------------------------------------------------------
//
//  Little Color Management System
//  Copyright (c) 1998-2017 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//---------------------------------------------------------------------------------
//

#include "lcms2_internal.h"

// Alpha copy ------------------------------------------------------------------------------------------------------------------

// Floor to byte, taking care of saturation
cmsINLINE cmsUInt8Number _cmsQuickSaturateByte(cmsFloat64Number d)
{
       d += 0.5;
       if (d <= 0) return 0;
       if (d >= 255.0) return 255;

       return (cmsUInt8Number) _cmsQuickFloorWord(d);
}


// Return the size in bytes of a given formatter
static
cmsUInt32Number trueBytesSize(cmsUInt32Number Format)
{
    cmsUInt32Number fmt_bytes = T_BYTES(Format);

    // For double, the T_BYTES field returns zero
    if (fmt_bytes == 0)
        return sizeof(double);

    // Otherwise, it is already correct for all formats
    return fmt_bytes;
}


// Several format converters

typedef void(*cmsFormatterAlphaFn)(void* dst, const void* src);


// From 8

static
void copy8(void* dst, const void* src)
{
       memmove(dst, src, 1);
}

static
void from8to16(void* dst, const void* src)
{
       cmsUInt8Number n = *(cmsUInt8Number*)src;
       *(cmsUInt16Number*) dst = FROM_8_TO_16(n);
}

static
void from8toFLT(void* dst, const void* src)
{
       *(cmsFloat32Number*)dst = (*(cmsUInt8Number*)src) / 255.0f;
}

static
void from8toDBL(void* dst, const void* src)
{
       *(cmsFloat64Number*)dst = (*(cmsUInt8Number*)src) / 255.0;
}

static
void from8toHLF(void* dst, const void* src)
{
#ifndef CMS_NO_HALF_SUPPORT
       cmsFloat32Number n = (*(cmsUInt8Number*)src) / 255.0f;
       *(cmsUInt16Number*)dst = _cmsFloat2Half(n);
#else
    cmsUNUSED_PARAMETER(dst);
    cmsUNUSED_PARAMETER(src);
#endif
}

// From 16

static
void from16to8(void* dst, const void* src)
{
       cmsUInt16Number n = *(cmsUInt16Number*)src;
       *(cmsUInt8Number*) dst = FROM_16_TO_8(n);
}

static
void copy16(void* dst, const void* src)
{
       memmove(dst, src, 2);
}

void from16toFLT(void* dst, const void* src)
{
       *(cmsFloat32Number*)dst = (*(cmsUInt16Number*)src) / 65535.0f;
}

void from16toDBL(void* dst, const void* src)
{
       *(cmsFloat64Number*)dst = (*(cmsUInt16Number*)src) / 65535.0f;
}

static
void from16toHLF(void* dst, const void* src)
{
#ifndef CMS_NO_HALF_SUPPORT
       cmsFloat32Number n = (*(cmsUInt16Number*)src) / 65535.0f;
       *(cmsUInt16Number*)dst = _cmsFloat2Half(n);
#else
    cmsUNUSED_PARAMETER(dst);
    cmsUNUSED_PARAMETER(src);
#endif
}

// From Float

static 
void fromFLTto8(void* dst, const void* src)
{
       cmsFloat32Number n = *(cmsFloat32Number*)src;   
       *(cmsUInt8Number*)dst = _cmsQuickSaturateByte(n * 255.0f);
}

static
void fromFLTto16(void* dst, const void* src)
{
       cmsFloat32Number n = *(cmsFloat32Number*)src;      
       *(cmsUInt16Number*)dst = _cmsQuickSaturateWord(n * 65535.0f);
}

static
void copy32(void* dst, const void* src)
{
       memmove(dst, src, sizeof(cmsFloat32Number));
}

static
void fromFLTtoDBL(void* dst, const void* src)
{
       cmsFloat32Number n = *(cmsFloat32Number*)src;
       *(cmsFloat64Number*)dst = (cmsFloat64Number)n;
}

static
void fromFLTtoHLF(void* dst, const void* src)
{
#ifndef CMS_NO_HALF_SUPPORT
       cmsFloat32Number n = *(cmsFloat32Number*)src;
       *(cmsUInt16Number*)dst = _cmsFloat2Half(n);
#else
    cmsUNUSED_PARAMETER(dst);
    cmsUNUSED_PARAMETER(src);
#endif
}


// From HALF

static
void fromHLFto8(void* dst, const void* src)
{
#ifndef CMS_NO_HALF_SUPPORT
       cmsFloat32Number n = _cmsHalf2Float(*(cmsUInt16Number*)src);
       *(cmsUInt8Number*)dst = _cmsQuickSaturateByte(n * 255.0f);
#else
    cmsUNUSED_PARAMETER(dst);
    cmsUNUSED_PARAMETER(src);
#endif

}

static
void fromHLFto16(void* dst, const void* src)
{
#ifndef CMS_NO_HALF_SUPPORT
       cmsFloat32Number n = _cmsHalf2Float(*(cmsUInt16Number*)src);
       *(cmsUInt16Number*)dst = _cmsQuickSaturateWord(n * 65535.0f);
#else
    cmsUNUSED_PARAMETER(dst);
    cmsUNUSED_PARAMETER(src);
#endif
}

static
void fromHLFtoFLT(void* dst, const void* src)
{
#ifndef CMS_NO_HALF_SUPPORT
       *(cmsFloat32Number*)dst = _cmsHalf2Float(*(cmsUInt16Number*)src);
#else
    cmsUNUSED_PARAMETER(dst);
    cmsUNUSED_PARAMETER(src);
#endif
}

static
void fromHLFtoDBL(void* dst, const void* src)
{
#ifndef CMS_NO_HALF_SUPPORT
       *(cmsFloat64Number*)dst = (cmsFloat64Number)_cmsHalf2Float(*(cmsUInt16Number*)src);
#else
    cmsUNUSED_PARAMETER(dst);
    cmsUNUSED_PARAMETER(src);
#endif
}

// From double
static
void fromDBLto8(void* dst, const void* src)
{
       cmsFloat64Number n = *(cmsFloat64Number*)src;
       *(cmsUInt8Number*)dst = _cmsQuickSaturateByte(n * 255.0);
}

static
void fromDBLto16(void* dst, const void* src)
{
       cmsFloat64Number n = *(cmsFloat64Number*)src;
       *(cmsUInt16Number*)dst = _cmsQuickSaturateWord(n * 65535.0f);
}

static
void fromDBLtoFLT(void* dst, const void* src)
{
       cmsFloat64Number n = *(cmsFloat64Number*)src;
       *(cmsFloat32Number*)dst = (cmsFloat32Number) n;
}

static
void fromDBLtoHLF(void* dst, const void* src)
{
#ifndef CMS_NO_HALF_SUPPORT
       cmsFloat32Number n = (cmsFloat32Number) *(cmsFloat64Number*)src;
       *(cmsUInt16Number*)dst = _cmsFloat2Half(n);
#else
    cmsUNUSED_PARAMETER(dst);
    cmsUNUSED_PARAMETER(src);
#endif
}

static
void copy64(void* dst, const void* src)
{
       memmove(dst, src, sizeof(cmsFloat64Number));
}


// Returns the position (x or y) of the formatter in the table of functions
static
int FormatterPos(cmsUInt32Number frm)
{
    cmsUInt32Number  b = T_BYTES(frm);

    if (b == 0 && T_FLOAT(frm))
        return 4; // DBL
#ifndef CMS_NO_HALF_SUPPORT
    if (b == 2 && T_FLOAT(frm))
        return 2; // HLF
#endif
    if (b == 4 && T_FLOAT(frm))
        return 3; // FLT
    if (b == 2 && !T_FLOAT(frm))
        return 1; // 16
    if (b == 1 && !T_FLOAT(frm))
        return 0; // 8

    return -1; // not recognized
}

// Obtains a alpha-to-alpha funmction formatter
static
cmsFormatterAlphaFn _cmsGetFormatterAlpha(cmsContext id, cmsUInt32Number in, cmsUInt32Number out)
{
static const cmsFormatterAlphaFn FormattersAlpha[5][5] = {

       /* from 8 */  { copy8,      from8to16,   from8toHLF,   from8toFLT,   from8toDBL   },
       /* from 16*/  { from16to8,  copy16,      from16toHLF,  from16toFLT,  from16toDBL  },
       /* from HLF*/ { fromHLFto8, fromHLFto16, copy16,       fromHLFtoFLT, fromHLFtoDBL },
       /* from FLT*/ { fromFLTto8, fromFLTto16, fromFLTtoHLF, copy32,       fromFLTtoDBL },
       /* from DBL*/ { fromDBLto8, fromDBLto16, fromDBLtoHLF, fromDBLtoFLT, copy64 }};

        int in_n  = FormatterPos(in);
        int out_n = FormatterPos(out);

        if (in_n < 0 || out_n < 0 || in_n > 4 || out_n > 4) {

               cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized alpha channel width");
               return NULL;
        }

        return FormattersAlpha[in_n][out_n];
}



// This function computes the distance from each component to the next one in bytes. 
static
void ComputeIncrementsForChunky(cmsUInt32Number Format,                                 
                                cmsUInt32Number ComponentStartingOrder[], 
                                cmsUInt32Number ComponentPointerIncrements[])
{
       cmsUInt32Number channels[cmsMAXCHANNELS];
       cmsUInt32Number extra = T_EXTRA(Format);
       cmsUInt32Number nchannels = T_CHANNELS(Format);
       cmsUInt32Number total_chans = nchannels + extra;
       cmsUInt32Number i;
       cmsUInt32Number channelSize = trueBytesSize(Format);
       cmsUInt32Number pixelSize = channelSize * total_chans;
       
	   // Sanity check
	   if (total_chans <= 0 || total_chans >= cmsMAXCHANNELS)
		   return;

        memset(channels, 0, sizeof(channels));

       // Separation is independent of starting point and only depends on channel size
       for (i = 0; i < extra; i++)
              ComponentPointerIncrements[i] = pixelSize;

       // Handle do swap
       for (i = 0; i < total_chans; i++)
       {
              if (T_DOSWAP(Format)) {
                     channels[i] = total_chans - i - 1;
              }
              else {
                     channels[i] = i;
              }
       }

       // Handle swap first (ROL of positions), example CMYK -> KCMY | 0123 -> 3012
       if (T_SWAPFIRST(Format) && total_chans > 1) {
              
              cmsUInt32Number tmp = channels[0];
              for (i = 0; i < total_chans-1; i++)
                     channels[i] = channels[i + 1];

              channels[total_chans - 1] = tmp;
       }

       // Handle size
       if (channelSize > 1)
              for (i = 0; i < total_chans; i++) {
                     channels[i] *= channelSize;
              }

       for (i = 0; i < extra; i++)
              ComponentStartingOrder[i] = channels[i + nchannels];
}



//  On planar configurations, the distance is the stride added to any non-negative
static
void ComputeIncrementsForPlanar(cmsUInt32Number Format, 
                                cmsUInt32Number BytesPerPlane,
                                cmsUInt32Number ComponentStartingOrder[], 
                                cmsUInt32Number ComponentPointerIncrements[])
{
       cmsUInt32Number channels[cmsMAXCHANNELS];       
       cmsUInt32Number extra = T_EXTRA(Format);
       cmsUInt32Number nchannels = T_CHANNELS(Format);
       cmsUInt32Number total_chans = nchannels + extra;
       cmsUInt32Number i;
       cmsUInt32Number channelSize = trueBytesSize(Format);
      
       // Sanity check
       if (total_chans <= 0 || total_chans >= cmsMAXCHANNELS)
           return;

       memset(channels, 0, sizeof(channels));

       // Separation is independent of starting point and only depends on channel size
       for (i = 0; i < extra; i++)
              ComponentPointerIncrements[i] = channelSize;

       // Handle do swap
       for (i = 0; i < total_chans; i++)
       {
              if (T_DOSWAP(Format)) {
                     channels[i] = total_chans - i - 1;
              }
              else {
                     channels[i] = i;
              }
       }

       // Handle swap first (ROL of positions), example CMYK -> KCMY | 0123 -> 3012
       if (T_SWAPFIRST(Format) && total_chans > 0) {

              cmsUInt32Number tmp = channels[0];
              for (i = 0; i < total_chans - 1; i++)
                     channels[i] = channels[i + 1];

              channels[total_chans - 1] = tmp;
       }

       // Handle size
       for (i = 0; i < total_chans; i++) {
              channels[i] *= BytesPerPlane;
       }

       for (i = 0; i < extra; i++)
              ComponentStartingOrder[i] = channels[i + nchannels];
}



// Dispatcher por chunky and planar RGB
static
void  ComputeComponentIncrements(cmsUInt32Number Format,
                                 cmsUInt32Number BytesPerPlane,
                                 cmsUInt32Number ComponentStartingOrder[], 
                                 cmsUInt32Number ComponentPointerIncrements[])
{
       if (T_PLANAR(Format)) {

              ComputeIncrementsForPlanar(Format,  BytesPerPlane, ComponentStartingOrder, ComponentPointerIncrements);
       }
       else {
              ComputeIncrementsForChunky(Format,  ComponentStartingOrder, ComponentPointerIncrements);
       }

}



// 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)
{
    cmsUInt32Number i, j, k;
    cmsUInt32Number nExtra;
    cmsUInt32Number SourceStartingOrder[cmsMAXCHANNELS];
    cmsUInt32Number SourceIncrements[cmsMAXCHANNELS];
    cmsUInt32Number DestStartingOrder[cmsMAXCHANNELS];
    cmsUInt32Number DestIncrements[cmsMAXCHANNELS];

    cmsFormatterAlphaFn copyValueFn;

    // Make sure we need some copy
    if (!(p->dwOriginalFlags & cmsFLAGS_COPY_ALPHA))
        return;

    // 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;

    // 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;

    // 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);

    if (nExtra == 1) { // Optimized routine for copying a single extra channel quickly

        cmsUInt8Number* SourcePtr;
        cmsUInt8Number* DestPtr;

        cmsUInt32Number SourceStrideIncrement = 0;
        cmsUInt32Number DestStrideIncrement = 0;

        // 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;
            }
        }
    }
}


