/**************************************************************************
 *{@C
 *      Copyright:      1988-2020 Paul Obermeier (obermeier@poSoft.de)
 *
 *      Module:         ImageProcessing
 *      Filename:       IP_ApplyLogo.c
 *
 *      Author:         Paul Obermeier
 *
 *      Description:    Function to apply a logo onto an image.
 *
 *      Additional documentation:
 *                      None.
 *
 *      Exported functions:
 *                      IP_ApplyLogo
 *
 **************************************************************************/

#include <stdio.h>

#include "UT_Compat.h"
#include "UT_Error.h"
#include "UT_Memory.h"
#include "UT_Parallel.h"

#define USE_IMG_MACROS
#include "FF_Image.h"

#include "IP_Image.h"
#include "IP_ImagePrivate.h"

/* #define DEBUG_LOCAL */

/***************************************************************************
 *[@e
 *      Name:           IP_ApplyLogo
 *
 *      Usage:          Put an image on top of another image.
 *
 *      Synopsis:       UT_Bool IP_ApplyLogo 
 *                              (IP_ImageId img, IP_ImageId logo,
 *                               Int32 x1, Int32 y1,
 *                               Float32 sr, Float32 sg, Float32 sb)
 *
 *      Description:    Put an image on top of another image.
 *
 *      Return value:   UT_Bool.
 *
 *      See also:
 *
 ***************************************************************************/

UT_Bool IP_ApplyLogo (IP_ImageId img, IP_ImageId logo, Int32 x1, Int32 y1,
                      Float32 sr, Float32 sg, Float32 sb)
{
    IP_ImageId logo2, cmp;
    FF_ImgHdr imgDesc, logoDesc;
    FF_ImgFmtType logofmt[FF_NumImgChanTypes] = { FF_ImgFmtTypeNone };
    FF_ImgFmtType pixfmt[FF_NumImgChanTypes]  = { FF_ImgFmtTypeNone };
    UT_Bool drawmask[FF_NumImgChanTypes]      = { UT_False };
    Float32 drawcolor[FF_NumImgChanTypes]     = { 1.0 };
    FF_ImgFmtType savepixfmt[FF_NumImgChanTypes];
    UT_Bool savedrawmask[FF_NumImgChanTypes];
    Float32 savedrawcolor[FF_NumImgChanTypes];
    Int32 lw, lh, iw, ih;
    Int32 chn;

    /* Save original drawing modes. */
    IP_GetFormat    (savepixfmt);
    IP_GetDrawMask  (savedrawmask);
    IP_GetDrawColor (savedrawcolor);

    IP_ImageInfo (img,  &imgDesc,  NULL);
    IP_ImageInfo (logo, &logoDesc, logofmt);
    iw = imgDesc.width;
    ih = imgDesc.height;
    lw = logoDesc.width;
    lh = logoDesc.height;

    #if defined (DEBUG_LOCAL)
        printf ("Image size: (%d %d) Logo size: (%d %d)\n", iw, ih, lw, lh);
    #endif

    for (chn = 0; chn < FF_NumImgChanTypes; ++chn) {
        pixfmt[(int)chn] = logofmt[(int)chn];
        if (logofmt[FF_ImgChanTypeMatte] == FF_ImgFmtTypeNone) 
            pixfmt[(int)FF_ImgChanTypeMatte] = FF_ImgFmtTypeUByte;

        #if defined (DEBUG_LOCAL)
            printf ("Channel %d: Logofmt: %d Pixfmt: %d\n",
                    chn, logofmt[(int)chn], pixfmt[(int)chn]);
        #endif
    }
    IP_SetFormat (pixfmt);

    if (!(logo2 = IP_ImageNew (lw, lh, logoDesc.aspect)) ||
        !(cmp   = IP_ImageNew (lw, lh, logoDesc.aspect)))
        return UT_False;

    for (chn = 0; chn < FF_NumImgChanTypes; ++chn)
        if (!IP_CopyChannel (logo, logo2, chn, chn))
            return UT_False;

    /* If logo does not supply a matte channel, we generate a white matte. */
    if (logofmt[FF_ImgChanTypeMatte] == FF_ImgFmtTypeNone) {
        #if defined (DEBUG_LOCAL)
            printf ("Generating white matte\n");
        #endif
        drawmask[(int)FF_ImgChanTypeMatte] = UT_True;
        IP_SetDrawMask  (drawmask);
        drawcolor[(int)FF_ImgChanTypeMatte] = 1.0;
        IP_SetDrawColor (drawcolor);
        IP_DrawRect (logo2, 0, 0, lw, lh, UT_True);
    }

    drawmask[(int)FF_ImgChanTypeRed]   = UT_True;
    drawmask[(int)FF_ImgChanTypeGreen] = UT_True;
    drawmask[(int)FF_ImgChanTypeBlue]  = UT_True;
    drawmask[(int)FF_ImgChanTypeMatte] = UT_True;
    IP_SetDrawMask (drawmask);
    
    if (!IP_ChangeGamma (logo2, FF_ImgChanTypeRed,   1.0, sr, 0.0) ||
        !IP_ChangeGamma (logo2, FF_ImgChanTypeGreen, 1.0, sg, 0.0) ||
        !IP_ChangeGamma (logo2, FF_ImgChanTypeBlue,  1.0, sb, 0.0))
        return UT_False;

    IP_Blank (cmp);
    IP_CopyRect (img, cmp, x1, ih - (y1 + lh), x1 + lw, ih - y1, 0, 0);

    if (!IP_CompositeAlpha (logo2, cmp, cmp, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
                           logo2, UT_True))
        return UT_False;

    drawmask[(int)FF_ImgChanTypeMatte] = UT_False;
    IP_SetDrawMask (drawmask);

    IP_CopyRect (cmp, img, 0, 0, lw - 1, lh - 1, x1, ih - (y1 + lh));

    IP_ImageDelete (cmp);
    IP_ImageDelete (logo2);

    /* Restore original drawing modes. */
    IP_SetFormat    (savepixfmt);
    IP_SetDrawMask  (savedrawmask);
    IP_SetDrawColor (savedrawcolor);

    return UT_True;
}
