/*
 * Copyright (C) 1997-2009, R3vis Corporation.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA, or visit http://www.gnu.org/copyleft/lgpl.html.
 *
 * Original Contributor:
 *   Wes Bethel, R3vis Corporation, Marin County, California
 *   http://www.r3vis.com/
 * Additional Contributor(s):
 *
 * The OpenRM project is located at http://openrm.sourceforge.net/.
 */
/*
 * $Id: rmvutil.c,v 1.6 2005/06/08 18:33:18 wes Exp $
 * Version: $Name: v180-alpha-02 $
 * $Revision: 1.6 $
 * $Log: rmvutil.c,v $
 * Revision 1.6  2005/06/08 18:33:18  wes
 * Code cleanup to eliminate compiler warnings.
 *
 * Revision 1.5  2005/02/19 16:09:13  wes
 * Distro sync and consolidation.
 *
 * Revision 1.4  2005/01/23 17:11:02  wes
 * Copyright updated to 2005.
 *
 * Revision 1.3  2004/01/17 04:09:26  wes
 * Updated copyright line for 2004.
 *
 * Revision 1.2  2003/02/02 02:07:23  wes
 * Updated copyright to 2003.
 *
 * Revision 1.1.1.1  2003/01/28 02:15:23  wes
 * Manual rebuild of rm150 repository.
 *
 * Revision 1.5  2003/01/16 22:21:20  wes
 * Updated all source files to reflect new organization of header files:
 * all header files formerly located in include/rmaux, include/rmi, include/rmv
 * are now located in include/rm.
 *
 * Revision 1.4  2002/04/30 19:40:37  wes
 * Updated copyright dates.
 *
 * Revision 1.3  2001/03/31 17:10:08  wes
 * v1.4.0-alpha-2 checkin.
 *
 * Revision 1.2  2000/04/17 00:05:24  wes
 * Lots of documentation updates, courtesy of jdb.
 *
 * Revision 1.1.1.1  2000/02/28 21:29:40  wes
 * OpenRM 1.2 Checkin
 *
 * Revision 1.1.1.1  2000/02/28 17:18:48  wes
 * Initial entry - pre-RM120 release, source base for OpenRM 1.2.
 *
 */


#include <rm/rm.h>
#include <rm/rmv.h>
#include "rmvprivt.h"



#define QUERY_SIGN(a,b) (((a) > (b)) ? 1 : ((a) < (b)) ? -1 : 0)

/* PRIVATE */
void
private_rmvInsertZeroCrossings (float *a,
			        int n,
			        float *oldx,
			        float *oldy,
			        float *oldz,
			        float *old_data2,
			        float **b,
			        float **newx,
			        float **newy,
			        float **newz,
			        int *m,
			        float **new_data2,
			        float zero_crossing_value)
{
    int    i, j, nzero_crossings;
    int    last_sign, this_sign;
    int    new_size;
    float *d, *x, *y, *z, *d2;

    nzero_crossings = 0;
    
    last_sign = QUERY_SIGN(a[0], zero_crossing_value);
    for (i = 1; i < n; i++)
    {
	this_sign = QUERY_SIGN(a[i], zero_crossing_value);

	if (last_sign != this_sign)
	{
	    if (!((last_sign == 0) || (this_sign == 0)))
		nzero_crossings++;
	}
	last_sign = this_sign;
    }

    new_size = n + nzero_crossings;
    d = *b = (float *)malloc(sizeof(float) * new_size);
    if ((new_data2) && (old_data2))
	d2 = *new_data2 = (float *)malloc(sizeof(float) * new_size);
    else
	d2 = NULL;
    
    if (newx)
	*newx = x = (float *)malloc(sizeof(float) * new_size);
    else
	x = NULL;
    
    if (newy)
	*newy = y = (float *)malloc(sizeof(float) * new_size);
    else
	y = NULL;
    
    if (newz)
	*newz = z = (float *)malloc(sizeof(float) * new_size);
    else
	z = NULL;

    *m = new_size;

    d[0] = a[0];
    if (x)
	x[0] = oldx[0];

    if (y)
	y[0] = oldy[0];

    if (z)
	z[0] = oldz[0];

    if (d2)
	d2[0] = old_data2[0];
    
    last_sign = QUERY_SIGN(a[0], zero_crossing_value);
    j = 1;
    for (i = 1; i < n; i++)
    {
	this_sign = QUERY_SIGN(a[i], zero_crossing_value);

	if (last_sign != this_sign)
	{
	    if (!((last_sign == 0) || (this_sign == 0)))
	    {
		float t;
		
		d[j] = zero_crossing_value;
		t = (a[i] - zero_crossing_value) / (a[i] - a[i - 1]);
		
		if (x)
		    x[j] = oldx[i] - (t * (oldx[i] - oldx[i - 1]));

		if (y)
		    y[j] = oldy[i] - (t * (oldy[i] - oldy[i - 1]));

		if (z)
		    z[j] = oldz[i] - (t * (oldz[i] - oldz[i - 1]));

		if (d2)
		    d2[j] = old_data2[i] - (t * (old_data2[i] - old_data2[i - 1]));
		j++;
		
		d[j] = a[i];
		if (x)
		    x[j] = oldx[i];

		if (y)
		    y[j] = oldy[i];

		if (z)
		    z[j] = oldz[i];

		if (d2)
		    d2[j] = old_data2[i];
	    }
	    else
	    {
		d[j] = a[i];

		if (x)
		    x[j] = oldx[i];

		if (y)
		    y[j] = oldy[i];

		if (z)
		    z[j] = oldz[i];

		if (d2)
		    d2[j] = old_data2[i];
	    }
	}
	else
	{
	    d[j] = a[i];

	    if (x)
		x[j] = oldx[i];

	    if (y)
		y[j] = oldy[i];

	    if (z)
		z[j] = oldz[i];

	    if (d2)
		d2[j] = old_data2[i];
	}
	j++;
	last_sign = this_sign;
    }
}


/* PRIVATE */
void
convert_from_map (unsigned char *rgba,
		  void *vmap,
		  int w,
		  int h,
		  int depth,
		  unsigned char *src)
{
    unsigned char *d;
    int            i, index;
    float          c[4];
    RMvisMap      *v;


    d = rgba;
    v = (RMvisMap *)vmap;

    for (i = 0; i < (w * h * depth); i++)
    {
	float ss;

	ss = (float)src[i];
	ss /= 255.0;
	index = rmVismapIndexFromData(v, ss);
	rmVismapGetColor4D(v, index, (RMcolor4D *)c);

	*d++ = (unsigned char)(c[0] * 255.0);
	*d++ = (unsigned char)(c[1] * 255.0);
	*d++ = (unsigned char)(c[2] * 255.0);
	*d++ = (unsigned char)(c[3] * 255.0);
    }
}


/* PRIVATE */
void
convert_from_a (unsigned char *rgba,
	        int w,
	        int h,
	        int depth,
	        unsigned char *src)
{
    unsigned char *d;
    int            i;

    d = rgba;

    for (i = 0; i < (w * h * depth); i++)
    {
	*d++ = src[i];
	*d++ = src[i];
	*d++ = src[i];
	*d++ = src[i];
    }
}
/* EOF */
