/*
 * $Id: image_oquant.c,v 0.14 1999/01/16 07:29:24 zhao Exp $
 *
 * Copyright (c)  1998-1999 T.C. Zhao
 *
 *  A color quantizer based on octree algorithm. The algorithm
 *  is implemented and copyright by Steve Lamont (spl@ucsd.edu)
 *  Copyright (C) 1998, Steve Lamont and the National Center for Microscopy 
 *                      and Imaging Research
 *
 *  Contact Steve for the latest version of the quantization library.
 */

#include "forms.h"
#include "quantize.h"

void fl_select_octree_quantizer(void)
{
   flimage_quantize_rgb = fl_octree_quantize_rgb;
   flimage_quantize_packed  = fl_octree_quantize_packed;
}

int
fl_octree_quantize_rgb(unsigned char **red,
		       unsigned char **green,
		       unsigned char **blue, int w, int h,
		       int max_color,
		       unsigned short **ci, int *actual_color,
		       int *red_lut,
		       int *green_lut,
		       int *blue_lut, FL_IMAGE * im)
{
    int i, j;
    unsigned int *rlut, *glut, *blut;
    QuantizeDatabaseP database = QuantizeInitialize(max_color,
						    QuantizeStyleLeast);
    if (im)
    {
	im->completed = 0;
	im->visual_cue(im, "Starting OctreeQuantizer ...");
    }

    for (i = 0; i < h; i++)
	for (j = 0; j < w; j++)
	    QuantizeColor(database, red[i][j], green[i][j], blue[i][j]);

    QuantizeCreateLUT(database, actual_color,
		      &rlut, &glut, &blut);

    for (i = 0; i < *actual_color; i++)
    {
	red_lut[i] = rlut[i];
	green_lut[i] = glut[i];
	blue_lut[i] = blut[i];
    }

    free(rlut);
    free(glut);
    free(blut);

    for (i = 0; i < h; i++)
	for (j = 0; j < w; j++)
	    ci[i][j] = QuantizeFindIndex(database,
					 red[i][j], green[i][j], blue[i][j]);


    QuantizeDatabaseFree(database);

    if (im)
    {
	im->completed = im->total;
	im->visual_cue(im, "Done OctreeQuantizer");
    }
    return 0;
}

int
fl_octree_quantize_packed(unsigned int **packed, int w, int h,
		      int max_color, unsigned short **ci, int *actual_color,
			  int *red_lut, int *green_lut, int *blue_lut,
			  FL_IMAGE * im)
{
    int i, n = h * w;
    unsigned int *p;
    unsigned short *ind;
    unsigned int *rlut, *glut, *blut;

    QuantizeDatabaseP database = QuantizeInitialize(max_color,
						    QuantizeStyleLeast);
    if (im)
    {
	im->completed = 0;
	im->visual_cue(im, "Starting OctreeQuantizer ...");
    }

    for (p = packed[0], i = 0; i < n; i++, p++)
	QuantizeColor(database, FL_GETR(*p), FL_GETG(*p), FL_GETB(*p));

    QuantizeCreateLUT(database, actual_color, &rlut, &glut, &blut);
    for (i = 0; i < *actual_color; i++)
    {
	red_lut[i] = rlut[i];
	green_lut[i] = glut[i];
	blue_lut[i] = blut[i];
    }

    free(rlut);
    free(glut);
    free(blut);


    for (ind = ci[0], p = packed[0], i = 0; i < n; i++, p++, ind++)
	*ind = QuantizeFindIndex(database,
				 FL_GETR(*p), FL_GETG(*p), FL_GETB(*p));

    QuantizeDatabaseFree(database);

    if (im)
    {
	im->completed = im->total;
	im->visual_cue(im, "Done OctreeQuantizer");
    }
    return 0;
}
