// scale-to-uchar.c
//      Copyright 1994, Center for Computer Vision and Visualization,
//      University of Florida.  All rights reserved.
// Scale an FDI or IDI image to a UDI image by using a linear scaling.
// The images are scaled into the [0..255] u_char value range,
//      by using a simple linear scaling.

#include "scale-to-uchar.h"

template <class P, class T>
IA_Image<IA_Point<int>,u_char>
scale_to_uchar( const IA_Image<P,T> & image_to_scale ){

    IA_Array<T>  t_values = image_to_scale.value_array();

    // Find the max and min elements of the image
    // We could do this with max() and min(), but this
    //   should be faster, because we get both in one loop.

    unsigned int t_len = t_values.len();
    T *tvp = t_values.data_start();
    T t_min = *tvp, t_max = *tvp, tmp;

    tvp++;  // Skip the first value, we have it already.
    for( int i=1; i<t_len; i++, tvp++ ) {
	tmp = *tvp;
	if (tmp < t_min) t_min = tmp;
	if (tmp > t_max) t_max = tmp;
    }

    cerr << __FILE__ << "::scale-to-uchar: t_min = " << t_min
	 << "\tt_max = " << t_max << endl;


    // Now build the result image range by scaling.
    // First allocate space for it.
    u_char *udi_values = new u_char[ t_len ];

    // To map a value  x in [t_min .. t_max] onto the range [0..255]
    //   we calculate the new value as  255*(x-t_min)/(t_max-t_min)

    t_max -= t_min;  // Adjust t_max once.
    double t_const( 255.0/double(t_max) );
    for( i=0; i<t_len; i++ ) {
	udi_values[i] = u_char( t_const * (t_values[i] - t_min) );
    }
    const int ASSUME_STORAGE_MGT = 1;

    return
	IA_Image<IA_Point<int>,u_char>( image_to_scale.domain(),
					udi_values,
					t_len,
					ASSUME_STORAGE_MGT );
}
