/**************************************************************************
 *{@C
 *      Copyright:      1988-2024 Paul Obermeier (obermeier@poSoft.de)
 *
 *      Module:         ImageProcessing
 *      Filename:       IP_ImagePrivate.h
 *
 *      Author:         Paul Obermeier
 *
 *      Usage:  Declaration of the data types and functions
 *                      used internally by the image processing library.
 *
 *      Additional documentation:
 *                      None.
 *
 **************************************************************************/

#ifndef __IP_IMAGEPRIVATE_H__
#define __IP_IMAGEPRIVATE_H__

#include "UT_Compat.h"
#include "FF_Image.h"

/* Message strings */

#define str_range_exclusive     "%s must be greater than %g and less " \
                                "than or equal to %g"
#define str_range_inclusive     "%s must be in the range from %g to %g"
#define str_greater             "%s must be greater than %g"
#define str_notless             "%s must not be less than %g"
#define str_inotless            "%s must not be less than %d"
#define str_equal               "Images must be of the same size"
#define str_gamma               "gamma factor"
#define str_cie_hue             "CIE color value"
#define str_image_width         "image width in pixels"
#define str_image_height        "image height in pixels"
#define str_image_aspect        "image aspect ratio"
#define str_nkey                "number of key points"
#define str_istep               "sampling step size"
#define str_lutsize             "lookup table size"
#define str_periodlength        "period length"
#define str_numthread           "number of threads"
#define str_pixformat           "unknown pixel data format"
#define str_compression         "unknown data compression method"
#define str_drawmode            "unknown drawing mode"
#define str_fipmode             "unknown field interpolation mode"
#define str_fg_bwtrans          "foreground image has no black and white " \
                                "transparency channel"
#define str_mt_bwtrans          "matte image has no black and white " \
                                "transparency channel"
#define str_fg_clrtrans         "foreground image has no red, green and " \
                                "blue transparency channels"
#define str_mt_clrtrans         "matte image has no red, green and " \
                                "blue transparency channels"
#define str_fg_depth            "foreground image has no depth channel"
#define str_bg_depth            "background image has no depth channel"
#define str_imgchan             "invalid image channel: %s"
#define str_oormode             "invalid 'out of range' pixel filling mode: %d"
#define str_cant_write          "Cannot write pixel file '%s'"
#define str_cant_read           "Cannot read pixel file '%s'"
#define str_shear_mt            "Pixel displacement parameters are too big"
#define str_correl_rect         "Data source rectange for pixel correlation " \
                                "is not within the boundaries of the source " \
                                "image"
#define str_find_rects          "Image region to be searched is smaller " \
                                "than the pattern to be found"
#define str_rgb_ubyte           "Image must have red, green and blue channels" \
                                "in FF_ImgFmtTypeUByte format."
#define str_chn_ubyte           "Image must have a channel " \
                                "in FF_ImgFmtTypeUByte format."
#define str_invalid_pixel       "Pixel (%d, %d) is not within image"

/* An IP_ImageId */

typedef struct IP_ImageStruct {
    FF_ImgDesc pimg;
} IP_ImageStruct;

/* Variables defined in "IP_State.c" */

extern FF_ImgFmtType IP_StateFormat[];
extern FF_ImgComprType IP_StateCompression[];
extern UT_Bool IP_StateDrawMask[];
extern UInt8 IP_StateDrawColorUByte[];
extern Float32 IP_StateDrawColorFloat[];
extern IP_DrawModeType IP_StateDrawMode[];
extern Float32 IP_StateGamma;
extern CIE_hue IP_StateHueRed;
extern CIE_hue IP_StateHueGreen;
extern CIE_hue IP_StateHueBlue;
extern CIE_hue IP_StateHueWhite;
extern Int32 IP_StateNumThreads;
extern Int32 IP_TextScale;

/* Minimum and maximum acceptable gamma correction factors */
#define MINGAMMA   0.01
#define MAXGAMMA 100.0

/* Number of entries in gamma-correction lookup tables for Float32 data */
#define GTABSIZE 4097


/* Given a pixel value in FF_ImgFmtTypeUByte format, "ubin", 
   and a gamma-correction lookup table, "ubtab", macro "gcorrect_UByte"
   returns the gamma-corrected pixel value in "ubout". */

#define gcorrect_UByte(ubin,ubtab,ubout) ((ubout) = (ubtab)[ubin])


/* Given a pixel value in FF_ImgFmtTypeUByte format, "ubin", 
   and a gamma-correction lookup table, "ftab", macro "gcorrect_UByte2" 
   returns the gamma-corrected pixel value, converted to FF_ImgFmtTypeFloat,
   in "fout". */

#define gcorrect_UByte2(ubin,ftab,fout) ((fout) = (ftab)[ubin])


/* Given a pixel value in FF_ImgFmtTypeFloat format, "fin", 
   and a gamma-correction lookup table, "ftab", macro "gcorrect_Float"
   returns the gamma-corrected pixel value in "fout". */

#define gcorrect_Float(fin,ftab,fout)                                   \
    {                                                                   \
        Int32   gc_i;                                                   \
        Float32 gc_t;                                                   \
        gc_t = (fin) * (GTABSIZE - 2);                                  \
        gc_i = (Int32)gc_t;                                             \
        gc_t -= gc_i;                                                   \
        (fout) = (ftab)[gc_i] * (1.0-gc_t) + (ftab)[gc_i+1] * gc_t;     \
    }



/* A pixel pyramid */

#define maxpyrlevels    31              /* Maximum number of levels
                                           in a pyramid */

typedef struct {
    Int32 maxlevel,                     /* Index of highest-resolution level
                                           in the pyramid */
          numchan;                      /* Number of channels in the pyramid */
    FF_ImgChanType
        channel[FF_NumImgChanTypes];    /* List of channels in the pyramid */
    Int32       *levtable;              /* Pointer to a log2 lookup table used
                                           to find pyramid levels quickly */
    Float32     lvtscale,               /* Scaling factor to transform
                                           sampling square sizes into lookup
                                           table indices */
                xmax, ymax,             /* Maximum x and y sampling coordinates
                                           allowed for this pyramid */
                xyscale1;               /* First sampling coordinate
                                           scaling factor */
    struct pyrlevel {                   /* The pyramid levels */
        Float32 xyscale2;               /* Second sampling coordinate
                                           scaling factor */
        Int32   width, height,          /* Number of columns and rows of pixel
                                           data stored in this level */
                rowbytes;               /* Bytes per row of pixel data */
        UInt8   *pixels;                /* Pointer to the pixel data */
    } pyrlevel[maxpyrlevels];
} pyramid;



/* Functions */

extern UT_Bool IP_UByteGammaTable  (Float32, UInt8[]);
extern UT_Bool IP_UByteGammaTable2 (Float32, Float32[]);
extern UT_Bool IP_FloatGammaTable  (Float32, Float32[]);

extern void IP_CopyUByte2UByte     (Int32, const UInt8[], UInt8[]);
extern void IP_CopyFloat2Float     (Int32, const Float32[], Float32[]);
extern void IP_CopyUByte2FloatAsIs (Int32, const UInt8[], Float32[]);
extern void IP_CopyUByte2Float     (Int32, const UInt8[], Float32[]);
extern void IP_CopyFloat2UByte     (Int32, const Float32[], UInt8[]);

extern void IP_GammaUByte2Float (Int32, const UInt8[], const Float32[], Float32[]);
extern void IP_GammaFloat2UByte (Int32, const Float32[], const Float32[], UInt8[]);
extern void IP_GammaFloat2Float (Int32, const Float32[], const Float32[], Float32[]);

extern pyramid *IP_GenPyramid (IP_ImageId);
extern void IP_SamplePyramid
        (pyramid *, Float32, Float32, Float32, Float32[], IP_FillModeType);

extern UT_Bool IP_CompSlowAlpha (IP_ImageId, IP_ImageId, IP_ImageId,
         Float32, Float32, Float32, Float32, Float32, Float32, IP_ImageId);
extern UT_Bool IP_CompSlowColorMatte (IP_ImageId, IP_ImageId, IP_ImageId,
         Float32, Float32, Float32, Float32, Float32, Float32, IP_ImageId);
extern UT_Bool IP_CompSlowDepth (IP_ImageId, IP_ImageId, IP_ImageId);
extern UT_Bool IP_CrossDissolveSlow (IP_ImageId, IP_ImageId, IP_ImageId, Float32);

extern UT_Bool IP_CompFastAlpha (IP_ImageId, IP_ImageId, IP_ImageId,
         Float32, Float32, Float32, Float32, Float32, Float32, IP_ImageId);
extern UT_Bool IP_CompFastColorMatte (IP_ImageId, IP_ImageId, IP_ImageId,
         Float32, Float32, Float32, Float32, Float32, Float32, IP_ImageId);
extern UT_Bool IP_CompFastDepth (IP_ImageId, IP_ImageId, IP_ImageId);
extern UT_Bool IP_CrossDissolveFast (IP_ImageId, IP_ImageId, IP_ImageId, Float32);

#endif /* __IP_IMAGEPRIVATE_H__ */
