/***************************************************************************
 *                                                                         *
 * Module  : palquant.h                                                        *
 *                                                                         *
 * Purpose :                                                               *
 *                                                                         *
 **************************************************************************/

#ifndef PALQUANT_H
#define PALQUANT_H

/****************************************************************************
 Includes
 */

/****************************************************************************
 Defines
 */
/* caching weights at every node improves performance at expense of memory */
#define CACHEWEIGHTSx

/****************************************************************************
 Global Types
 */

typedef struct box box;
struct box
{
	RwRGBA col0;	/* min value, inclusive */
	RwRGBA col1;	/* max value, exclusive */
};



#ifdef CACHEWEIGHTS
typedef struct OctNode OctNode;
#else
typedef union OctNode OctNode;
#endif

typedef struct LeafNode LeafNode;
struct LeafNode
{
	RwReal weight;
	RwRGBAReal ac;
	RwReal m2;
	RwUInt8 palIndex;
};

typedef struct BranchNode BranchNode;
struct BranchNode
{
	OctNode *dir[16];
};

#ifdef CACHEWEIGHTS
struct OctNode
#else
union OctNode
#endif
{
	LeafNode   Leaf;
	BranchNode Branch;
};

/* working data */
typedef struct rwPalQuant rwPalQuant;
struct rwPalQuant
{
	box *Mcube;
	float *Mvv;
	OctNode *root;
	RwFreeList *cubefreelist;
};

/****************************************************************************
 Function prototypes
 */

#ifdef    __cplusplus
extern          "C"
{
#endif         /* __cplusplus */

extern RwBool
_rwPalQuantInit(rwPalQuant *pq);


extern void
_rwPalQuantTerm(rwPalQuant *pq);


extern void
_rwPalQuantAddImage(rwPalQuant *pq, RwImage *img, RwReal weight);


extern RwInt32
_rwPalQuantResolvePalette(RwRGBA *palette, RwInt32 maxcols, rwPalQuant *pq);


extern void
_rwPalQuantMatchImage(RwUInt8 *dstpixels, RwInt32 dststride, RwInt32 dstdepth, 
                      RwBool dstPacked, rwPalQuant *pq, RwImage *img);

#define rwPalQuantInit(pq) \
       _rwPalQuantInit(pq)

#define rwPalQuantTerm(pq) \
       _rwPalQuantTerm(pq) 

#define rwPalQuantAddImage(pq, img, weight) \
       _rwPalQuantAddImage(pq, img, weight)

#define rwPalQuantResolvePalette(palette, maxcols, pq) \
       _rwPalQuantResolvePalette(palette, maxcols, pq)

#define rwPalQuantMatchImage(dstpixels, dststride, dstdepth, dstPacked, pq, img) \
       _rwPalQuantMatchImage(dstpixels, dststride, dstdepth, dstPacked, pq, img)


#ifdef    __cplusplus
}
#endif         /* __cplusplus */

#endif /* PALQUANT_H */
