/**************************************************************************
 *{@C
 *      Copyright:      1988-2023 Paul Obermeier (obermeier@poSoft.de)
 *
 *      Module:         ImageProcessing
 *      Filename:       IPT_TclIfSingle.c
 *
 *      Author:         Paul Obermeier
 *
 *      Description:    The interface between the image
 *                      library and the Tcl interpreter.
 *                      This file contains all non-thread-aware functions.
 *
 *      Additional documentation:
 *                      None.
 *
 *      Exported functions:
 *
 **************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#include "UT_Compat.h"

#include "UT_Error.h"
#include "UT_Memory.h"
#include "FF_Image.h"
#include "IP_Image.h"

#include <tcl.h>
#include "UTT_TclIf.h"
#include "IPT_TclIf.h"
#include "IPT_ImagePrivate.h"

/*>@u
        1. General information:
        =======================

        The following symbolic names and their numerical values 
        can be used as aequivalents:

        OFF     UT_False 0
        ON      UT_True  1

        A value of type "boolean" can be specified with one of these values.

        2. Channel type:
        ================

        There are currently 11 possible channel types.
        Their Tcl symbolic names as well as their 
        numerical values are listed below:

        BRIGHTNESS       0      Brightness for black and white images
        RED              1      Red for color images
        GREEN            2      Green for color images
        BLUE             3      Blue for color images
        MATTE            4      Transparency without color information
        REDMATTE         5      Transparency for red light
        GREENMATTE       6      Transparency for green light
        BLUEMATTE        7      Transparency for blue light
        HNORMAL          8      Direction of surface normal, horizontal
        VNORMAL          9      Direction of surface normal, vertical
        DEPTH           10      Distance from the eye point
        NUMCHAN         11      Number of different channel types

        3. Channel format:
        ==================

        The data stored in a channel can be in the following different formats:

        OFF              0      Channel is not used
        UBYTE            1      Channel holds 8-bit integer values (i.e. 0..255)
        FLOAT            2      Channel holds 32-bit floating point values 

        4. Image compression:
        =====================

        A channel can be compressed using one of the following methods:

        OFF             0       No compression.
        RLE             1       Lossless compression, e.g. run length encoding
        DCT             2       Lossy compression, e.g. DCT compression

        5. Drawing mode:
        ================

        The following different drawing modes are available:

        REPLACE         0       Replace old color with current color
        ADD             1       Add old color and current color
        SUB             2       Subtract old color from current color
        XOR             3       Exclusive-or old color and current color

<*/

UT_Bool IPT_GetFmtTypeName (TCLPARAMLIST)
{
    Int32 fmtType;
    const char *fmtTypeName;

    UTT_GetFixInt32 (1, fmtType);
    fmtTypeName = FF_ImgGetFmtTypeName ((FF_ImgFmtType)fmtType);
    UTT_SetFixStringResult ((char *)fmtTypeName);
    return UT_True;
}

UT_Bool IPT_GetChanTypeName (TCLPARAMLIST)
{
    Int32 chanType;
    const char *chanTypeName;

    UTT_GetFixInt32 (1, chanType);
    chanTypeName = FF_ImgGetChanTypeName ((FF_ImgChanType)chanType);
    UTT_SetFixStringResult ((char *)chanTypeName);
    return UT_True;
}

UT_Bool IPT_GetComprTypeName (TCLPARAMLIST)
{
    Int32 comprType;
    const char *comprTypeName;

    UTT_GetFixInt32 (1, comprType);
    comprTypeName = FF_ImgGetComprTypeName ((FF_ImgComprType)comprType);
    UTT_SetFixStringResult ((char *)comprTypeName);
    return UT_True;
}

UT_Bool IPT_SetFormat (TCLPARAMLIST)
{
    Int32 i, n, *fmt;
    FF_ImgFmtType tmp[FF_NumImgChanTypes];

    UTT_GetFixInt32List (1, fmt, n, FF_NumImgChanTypes);
    for (i=0; i<FF_NumImgChanTypes; i++)
        tmp[i] = fmt[i];
    UT_MemFree (fmt);
    return IP_SetFormat (tmp);
}

UT_Bool IPT_GetFormat (TCLPARAMLIST)
{
    Int32 i, fmt[FF_NumImgChanTypes];
    FF_ImgFmtType tmp[FF_NumImgChanTypes];

    IP_GetFormat (tmp);
    for (i=0; i<FF_NumImgChanTypes; i++)
        fmt[i] = tmp[i];
    UTT_SetFixInt32List (1, fmt, FF_NumImgChanTypes);
    return UT_True;
}

UT_Bool IPT_SetCompression (TCLPARAMLIST)
{
    Int32 i, n, *cmp;
    FF_ImgComprType tmp[FF_NumImgChanTypes];

    UTT_GetFixInt32List (1, cmp, n, FF_NumImgChanTypes);
    for (i=0; i<FF_NumImgChanTypes; i++)
        tmp[i] = cmp[i];
    UT_MemFree (cmp);
    return IP_SetCompression (tmp);
}

UT_Bool IPT_GetCompression (TCLPARAMLIST)
{
    Int32 i, cmp[FF_NumImgChanTypes];
    FF_ImgComprType tmp[FF_NumImgChanTypes];

    IP_GetCompression (tmp);
    for (i=0; i<FF_NumImgChanTypes; i++)
        cmp[i] = tmp[i];
    UTT_SetFixInt32List (1, cmp, FF_NumImgChanTypes);
    return UT_True;
}

UT_Bool IPT_SetDrawMask (TCLPARAMLIST)
{
    Int32 i, n, *msk;
    UT_Bool tmp[FF_NumImgChanTypes];

    UTT_GetFixInt32List (1, msk, n, FF_NumImgChanTypes);
    for (i=0; i<FF_NumImgChanTypes; i++)
        tmp[i] = msk[i];
    UT_MemFree(msk);
    return IP_SetDrawMask (tmp);
}

UT_Bool IPT_GetDrawMask (TCLPARAMLIST)
{
    Int32 i, msk[FF_NumImgChanTypes];
    UT_Bool tmp[FF_NumImgChanTypes];

    IP_GetDrawMask (tmp);
    for (i=0; i<FF_NumImgChanTypes; i++)
        msk[i] = tmp[i];
    UTT_SetFixInt32List (1, msk, FF_NumImgChanTypes);
    return UT_True;
}

UT_Bool IPT_SetDrawColor (TCLPARAMLIST)
{
    Int32 n;
    UT_Bool ret;
    Float32 *clr;

    UTT_GetFixFloat32List (1, clr, n, FF_NumImgChanTypes);
    ret = IP_SetDrawColor (clr);
    UT_MemFree (clr);
    return ret;
}

UT_Bool IPT_GetDrawColor (TCLPARAMLIST)
{
    Float32 clr[FF_NumImgChanTypes];

    IP_GetDrawColor (clr);
    UTT_SetFixFloat32List (1, clr, FF_NumImgChanTypes);
    return UT_True;
}

UT_Bool IPT_SetDrawMode (TCLPARAMLIST)
{
    Int32 i, n, *dm;
    IP_DrawModeType tmp[FF_NumImgChanTypes];

    UTT_GetFixInt32List (1, dm, n, FF_NumImgChanTypes);
    for (i=0; i<FF_NumImgChanTypes; i++) {
        tmp[i] = dm[i];
    }
    UT_MemFree (dm);
    return IP_SetDrawMode (tmp);
}

UT_Bool IPT_GetDrawMode (TCLPARAMLIST)
{
    Int32 i, dm[FF_NumImgChanTypes];
    IP_DrawModeType tmp[FF_NumImgChanTypes];

    IP_GetDrawMode (tmp);
    for (i=0; i<FF_NumImgChanTypes; i++)
        dm[i] = tmp[i];
    UTT_SetFixInt32List (1, dm, FF_NumImgChanTypes);
    return UT_True;
}

UT_Bool IPT_SetColorCorrect (TCLPARAMLIST)
{
    double gamma;
    double rx, ry, gx, gy, bx, by, wx, wy;
    CIE_hue red, green, blue, white;

    UTT_GetFixFloat64 (1, gamma);
    UTT_GetOptFloat64 (2, rx,   0.670);
    UTT_GetOptFloat64 (3, ry,   0.330);
    UTT_GetOptFloat64 (4, gx,   0.210);
    UTT_GetOptFloat64 (5, gy,   0.710);
    UTT_GetOptFloat64 (6, bx,   0.140);
    UTT_GetOptFloat64 (7, by,   0.080);
    UTT_GetOptFloat64 (8, wx,   0.313);
    UTT_GetOptFloat64 (9, wy,   0.329);

    red.x   = rx; red.y   = ry;
    green.x = gx; green.y = gy;
    blue.x  = bx; blue.y  = by;
    white.x = wx; white.y = wy;

    return IP_SetColorCorrect (gamma, &red, &green, &blue, &white);
}

UT_Bool IPT_GetColorCorrect (TCLPARAMLIST)
{
    Float32 gamma;
    CIE_hue red, green, blue, white;

    IP_GetColorCorrect (&gamma, &red, &green, &blue, &white);
    UTT_SetFixFloat64 (1, gamma);
    UTT_SetOptFloat64 (2, red.x);
    UTT_SetOptFloat64 (3, red.y);
    UTT_SetOptFloat64 (4, green.x);
    UTT_SetOptFloat64 (5, green.y);
    UTT_SetOptFloat64 (6, blue.x);
    UTT_SetOptFloat64 (7, blue.y);
    UTT_SetOptFloat64 (8, white.x);
    UTT_SetOptFloat64 (9, white.y);
    return UT_True;
}

UT_Bool IPT_SetNumThreads (TCLPARAMLIST)
{
    Int32 n;

    UTT_GetFixInt32 (1, n);
    return IP_SetNumThreads (n);
}

UT_Bool IPT_GetNumThreads (TCLPARAMLIST)
{
    UTT_SetFixInt32Result (IP_GetNumThreads ());
    return UT_True;
}

UT_Bool IPT_NewImage (OBJPARAMLIST)
{
    IP_ImageId img;
    Int32 w, h;
    double asp;

    UTT_GetFixInt32 (1, w);
    UTT_GetFixInt32 (2, h);
    UTT_GetOptFloat64 (3, asp, (Float32)w / (Float32)h);

    if (!(img = IP_NewImage (w, h, asp)))
        return UT_False;
    *clientData = img;
    return UT_True;
}

UT_Bool IPT_DeleteImage (ELEMPARAMLIST)
{
    IP_ImageId img = (IP_ImageId) clientData;
    IP_DeleteImage (img);
    return UT_True;
}

UT_Bool IPT_GetImageInfo (ELEMPARAMLIST)
{
    IP_ImageId img = (IP_ImageId) clientData;
    FF_ImgHdr desc;

    IP_GetImageInfo (img, &desc, NULL);

    UTT_SetFixInt32     (1, desc.width);
    UTT_SetFixInt32     (2, desc.height);
    UTT_SetOptFloat64  (3, desc.aspect);
    UTT_SetOptFloat64  (4, desc.gamma);
    UTT_SetOptFloat64  (5, desc.red.x);
    UTT_SetOptFloat64  (6, desc.red.y);
    UTT_SetOptFloat64  (7, desc.green.x);
    UTT_SetOptFloat64  (8, desc.green.y);
    UTT_SetOptFloat64  (9, desc.blue.x);
    UTT_SetOptFloat64 (10, desc.blue.y);
    UTT_SetOptFloat64 (11, desc.white.x);
    UTT_SetOptFloat64 (12, desc.white.y);
    return UT_True;
}

UT_Bool IPT_GetImageFormat (ELEMPARAMLIST)
{
    IP_ImageId img = (IP_ImageId) clientData;
    Int32 i, fmt[FF_NumImgChanTypes];
    FF_ImgFmtType tmp[FF_NumImgChanTypes];


    IP_GetImageInfo (img, NULL, tmp);
    for (i=0; i<FF_NumImgChanTypes; i++)
        fmt[i] = tmp[i];
    UTT_SetFixInt32List (1, fmt, FF_NumImgChanTypes);
    return UT_True;
}

UT_Bool IPT_WriteImage (ELEMPARAMLIST)
{
    IP_ImageId img = (IP_ImageId) clientData;
    char fname[MAXPATH + 1], fmt[Tmpsize], vsn[Tmpsize];

    UTT_GetFixString   (1, fname, MAXPATH + 1, UT_False);
    UTT_GetFixString   (2, fmt,   Tmpsize,     UT_False);
    UTT_GetFixString   (3, vsn,   Tmpsize,     UT_False);

    return IP_WriteImage (img, fname, fmt, vsn);
}

UT_Bool IPT_ReadImage (ELEMPARAMLIST)
{
    IP_ImageId img = (IP_ImageId) clientData;
    char fname[MAXPATH + 1];
    UT_Bool stretch, gamma, color;

    UTT_GetFixString (1, fname, MAXPATH + 1, UT_False);
    UTT_GetOptBool   (2, stretch, UT_False);
    UTT_GetOptBool   (3, gamma, UT_False);
    UTT_GetOptBool   (4, color, UT_False);

    return IP_ReadImage (img, fname, stretch, gamma, color);
}

UT_Bool IPT_GetFileInfo (TCLPARAMLIST)
{
    char  fname[MAXPATH + 1];
    FF_ImgHdr desc;

    UTT_GetFixString (1, fname, MAXPATH + 1, UT_False);

    if (!IP_GetFileInfo (fname, &desc, NULL))
        return UT_False;

    UTT_SetFixInt32    (2,  desc.width);
    UTT_SetFixInt32    (3,  desc.height);
    UTT_SetOptFloat64  (4,  desc.aspect);
    UTT_SetOptFloat64  (5,  desc.gamma);
    UTT_SetOptFloat64  (6,  desc.red.x);
    UTT_SetOptFloat64  (7,  desc.red.y);
    UTT_SetOptFloat64  (8,  desc.green.x);
    UTT_SetOptFloat64  (9,  desc.green.y);
    UTT_SetOptFloat64 (10,  desc.blue.x);
    UTT_SetOptFloat64 (11, desc.blue.y);
    UTT_SetOptFloat64 (12, desc.white.x);
    UTT_SetOptFloat64 (13, desc.white.y);
    return UT_True;
}

UT_Bool IPT_GetFileFormat (TCLPARAMLIST)
{
    Int32 i, fmt[FF_NumImgChanTypes];
    FF_ImgFmtType tmp[FF_NumImgChanTypes];
    char fname[MAXPATH + 1];

    UTT_GetFixString (1, fname, MAXPATH + 1, UT_False);

    if (!IP_GetFileInfo (fname, NULL, tmp))
        return UT_False;
    for (i=0; i<FF_NumImgChanTypes; i++)
        fmt[i] = tmp[i];

    UTT_SetFixInt32List (2, fmt, FF_NumImgChanTypes);
    return UT_True;
}

UT_Bool IPT_WriteSimple (ELEMPARAMLIST)
{
    IP_ImageId img = (IP_ImageId) clientData;
    char fname[MAXPATH + 1], fmt[Tmpsize], vsn[Tmpsize];

    UTT_GetFixString (1, fname, MAXPATH + 1, UT_False);
    UTT_GetFixString (2, fmt,   Tmpsize,     UT_False);
    UTT_GetFixString (3, vsn,   Tmpsize,     UT_False);

    return IP_WriteSimple (img, fname, fmt, vsn);
}

UT_Bool IPT_NewImageFromFile (OBJPARAMLIST)
{
    IP_ImageId img;
    char fname[MAXPATH + 1];

    UTT_GetFixString (1, fname, MAXPATH + 1, UT_False);
    if (!(img = IP_NewImageFromFile (fname)))
        return UT_False;
    *clientData = img;
    return UT_True;
}

UT_Bool IPT_DrawPixel (ELEMPARAMLIST)
{
    IP_ImageId img = (IP_ImageId) clientData;
    Int32 x, y;

    UTT_GetFixInt32 (1, x);
    UTT_GetFixInt32 (2, y);
    IP_DrawPixel  (img, x, y);
    return UT_True;
}

UT_Bool IPT_DrawLine (ELEMPARAMLIST)
{
    IP_ImageId img = (IP_ImageId) clientData;
    Int32 x1, y1;
    Int32 x2, y2;
    Int32 stipple;

    UTT_GetFixInt32 (1, x1);
    UTT_GetFixInt32 (2, y1);
    UTT_GetFixInt32 (3, x2);
    UTT_GetFixInt32 (4, y2);
    UTT_GetOptInt32 (5, stipple, 1);
    IP_DrawLine (img, x1, y1, x2, y2, stipple);
    return UT_True;
}

UT_Bool IPT_DrawRect (ELEMPARAMLIST)
{
    IP_ImageId img = (IP_ImageId) clientData;
    Int32 x1, y1;
    Int32 x2, y2;
    UT_Bool fill;

    UTT_GetFixInt32 (1, x1);
    UTT_GetFixInt32 (2, y1);
    UTT_GetFixInt32 (3, x2);
    UTT_GetFixInt32 (4, y2);
    UTT_GetOptBool  (5, fill, UT_True);
    IP_DrawRect (img, x1, y1, x2, y2, fill);
    return UT_True;
}

UT_Bool IPT_DrawEllipse (ELEMPARAMLIST)
{
    IP_ImageId img = (IP_ImageId) clientData;
    Int32 x, y;
    Int32 r1, r2;
    UT_Bool fill;

    UTT_GetFixInt32 (1, x);
    UTT_GetFixInt32 (2, y);
    UTT_GetFixInt32 (3, r1);
    UTT_GetFixInt32 (4, r2);
    UTT_GetOptBool  (5, fill, UT_True);
    IP_DrawEllipse (img, x, y, r1, r2, fill);
    return UT_True;
}

UT_Bool IPT_DrawCircle (ELEMPARAMLIST)
{
    IP_ImageId img = (IP_ImageId) clientData;
    Int32 x, y;
    Int32 r;
    UT_Bool fill;

    UTT_GetFixInt32 (1, x);
    UTT_GetFixInt32 (2, y);
    UTT_GetFixInt32 (3, r);
    UTT_GetOptBool  (4, fill, UT_True);
    IP_DrawCircle (img, x, y, r, fill);
    return UT_True;
}

UT_Bool IPT_DrawBrushLine (ELEMPARAMLIST)
{
    IP_ImageId img = (IP_ImageId) clientData;
    IP_ImageId bsh;
    Int32 x1, y1, x2, y2, nstroke;
    double intens;

    IPT_Get_Fix_Image  (1, bsh);
    UTT_GetFixInt32    (2, x1);
    UTT_GetFixInt32    (3, y1);
    UTT_GetFixInt32    (4, x2);
    UTT_GetFixInt32    (5, y2);
    UTT_GetOptInt32    (6, nstroke, 1);
    UTT_GetOptFloat64 (7, intens, 1.0);
    IP_DrawBrushLine (img, bsh, x1, y1, x2, y2, nstroke, intens);
    return UT_True;
}

UT_Bool IPT_DrawBrush (ELEMPARAMLIST)
{
    IP_ImageId img = (IP_ImageId) clientData;
    IP_ImageId bsh;
    Int32 xi, yi;
    double intens;

    IPT_Get_Fix_Image  (1, bsh);
    UTT_GetFixInt32    (2, xi);
    UTT_GetFixInt32    (3, yi);
    UTT_GetOptFloat64 (4, intens, 1.0);
    return IP_DrawBrush (img, bsh, xi, yi, intens);
}

UT_Bool IPT_MergeBrush (ELEMPARAMLIST)
{
    IP_ImageId img = (IP_ImageId) clientData;
    IP_ImageId backimg, bsh;
    Int32 xi, yi;
    double intens;

    IPT_Get_Fix_Image  (1, backimg);
    IPT_Get_Fix_Image  (2, bsh);
    UTT_GetFixInt32    (3, xi);
    UTT_GetFixInt32    (4, yi);
    UTT_GetOptFloat64 (5, intens, 1.0);
    return IP_MergeBrush (backimg, img, bsh, xi, yi, intens);
}

UT_Bool IPT_DrawText (ELEMPARAMLIST)
{
    IP_ImageId img = (IP_ImageId) clientData;
    Int32 x, y;
    char str[Tmpsize];

    UTT_GetFixInt32    (1, x);
    UTT_GetFixInt32    (2, y);
    UTT_GetFixString (3, str, Tmpsize, UT_False);
    IP_DrawText (img, x, y, str);
    return UT_True;
}

UT_Bool IPT_GetTextSize (TCLPARAMLIST)
{
    Int32 w, h;
    char str[Tmpsize];

    UTT_GetFixString (1, str, Tmpsize, UT_False);
    IP_GetTextSize (str, &w, &h);
    UTT_SetFixInt32 (2, w);
    UTT_SetFixInt32 (3, h);
    return UT_True;
}

UT_Bool IPT_SetTextScale (TCLPARAMLIST)
{
    Int32 n;

    UTT_GetFixInt32 (1, n);
    IP_SetTextScale (n);
    return UT_True;
}

UT_Bool IPT_GetTextScale (TCLPARAMLIST)
{
    UTT_SetFixInt32Result (IP_GetTextScale ());
    return UT_True;
}

UT_Bool IPT_BlankRect (ELEMPARAMLIST)
{
    IP_ImageId img = (IP_ImageId) clientData;
    Int32 x1, y1;
    Int32 x2, y2;

    UTT_GetFixInt32 (1, x1);
    UTT_GetFixInt32 (2, y1);
    UTT_GetFixInt32 (3, x2);
    UTT_GetFixInt32 (4, y2);
    IP_BlankRect (img, x1, y1, x2, y2);
    return UT_True;
}

UT_Bool IPT_Blank (ELEMPARAMLIST)
{
    IP_ImageId img = (IP_ImageId) clientData;
    IP_Blank (img);
    return UT_True;
}

UT_Bool IPT_GetPixel (ELEMPARAMLIST)
{
    IP_ImageId img = (IP_ImageId) clientData;
    Int32 x, y;
    Float32 color[FF_NumImgChanTypes] = { 0.0 };

    UTT_GetFixInt32 (1, x);
    UTT_GetFixInt32 (2, y);
    if (!IP_GetPixel (img, x, y, color)) {
        return UT_False;
    }
    UTT_SetFixFloat32List (3, color, FF_NumImgChanTypes);
    return UT_True;
}

UT_Bool IPT_CopyRect (ELEMPARAMLIST)
{
    IP_ImageId img = (IP_ImageId) clientData;
    IP_ImageId srcimg;
    Int32 xs1, ys1, xs2, ys2, xd1, yd1;

    IPT_Get_Fix_Image (1, srcimg);
    UTT_GetFixInt32   (2, xs1);
    UTT_GetFixInt32   (3, ys1);
    UTT_GetFixInt32   (4, xs2);
    UTT_GetFixInt32   (5, ys2);
    UTT_GetFixInt32   (6, xd1);
    UTT_GetFixInt32   (7, yd1);

    IP_CopyRect (srcimg, img, xs1, ys1, xs2, ys2, xd1, yd1);
    return UT_True;
}

UT_Bool IPT_WrapRect (ELEMPARAMLIST)
{
    IP_ImageId img = (IP_ImageId) clientData;
    IP_ImageId srcimg;
    Int32 xs1, ys1, xs2, ys2, sx, sy;

    IPT_Get_Fix_Image (1, srcimg);
    UTT_GetFixInt32   (2, xs1);
    UTT_GetFixInt32   (3, ys1);
    UTT_GetFixInt32   (4, xs2);
    UTT_GetFixInt32   (5, ys2);
    UTT_GetFixInt32   (6, sx);
    UTT_GetFixInt32   (7, sy);

    IP_WrapRect (srcimg, img, xs1, ys1, xs2, ys2, sx, sy);
    return UT_True;
}

UT_Bool IPT_CopyChannel (ELEMPARAMLIST)
{
    IP_ImageId img = (IP_ImageId) clientData;
    IP_ImageId srcimg;
    Int32 schn, dchn;

    IPT_Get_Fix_Image (1, srcimg);
    UTT_GetFixInt32   (2, schn);
    UTT_GetFixInt32   (3, dchn);
    return IP_CopyChannel (srcimg, img, schn, dchn);
}

UT_Bool IPT_CopyImage (ELEMPARAMLIST)
{
    IP_ImageId img = (IP_ImageId) clientData;
    IP_ImageId srcimg;

    IPT_Get_Fix_Image (1, srcimg);
    return IP_CopyImage (srcimg, img);
}

UT_Bool IPT_DrawAAPixel (ELEMPARAMLIST)
{
    IP_ImageId img = (IP_ImageId) clientData;
    double x, y;
    Float32 *clr;
    Int32 n;

    UTT_GetFixFloat64     (1, x);
    UTT_GetFixFloat64     (2, y);
    UTT_GetFixFloat32List (3, clr, n, FF_NumImgChanTypes);

    IP_DrawAAPixel (img, x, y, clr);
    UT_MemFree (clr);
    return UT_True;
}

UT_Bool IPT_DrawAALine (ELEMPARAMLIST)
{
    IP_ImageId img = (IP_ImageId) clientData;
    double x1, y1, x2, y2;
    Float32 *clr1, *clr2;
    Int32 n;

    UTT_GetFixFloat64     (1, x1);
    UTT_GetFixFloat64     (2, y1);
    UTT_GetFixFloat64     (3, x2);
    UTT_GetFixFloat64     (4, y2);
    UTT_GetFixFloat32List (5, clr1, n, FF_NumImgChanTypes);
    UTT_GetFixFloat32List (6, clr2, n, FF_NumImgChanTypes);

    IP_DrawAALine (img, x1, y1, x2, y2, clr1, clr2);
    UT_MemFree (clr1);
    UT_MemFree (clr2);
    return UT_True;
}

UT_Bool IPT_DrawAAText (ELEMPARAMLIST)
{
    IP_ImageId img = (IP_ImageId) clientData;
    double x, y;
    Float32 *clr;
    Int32 n;
    char str[Tmpsize];

    UTT_GetFixFloat64      (1, x);
    UTT_GetFixFloat64      (2, y);
    UTT_GetFixString      (3, str, Tmpsize, UT_False);
    UTT_GetFixFloat32List (4, clr, n, FF_NumImgChanTypes);

    IP_DrawAAText (img, x, y, str, clr);
    UT_MemFree (clr);
    return UT_True;
}
