/**************************************************************************
  Copyright (C) 1992 Guy Moreillon
  All rights reserved.

  This software may be freely copied, modified, and redistributed
  provided that this copyright notice is preserved on all copies.

  You may not distribute this software, in whole or in part, as part of
  any commercial product without the express consent of the authors.

  There is no warranty or other guarantee of fitness of this software
  for any purpose.  It is provided solely "as is".
**************************************************************************/
/**************************************************************************

				RAD
		       (Interactive Radiosity)
		    	    Version 1.0
			       1992		    	    
		    	    
		  
		    	  Guy Moreillon
			  Angelo Mangili
		    	  
**************************************************************************/

/**************************************************************************
  Fichier	: load_image.c
  Description	: Routines de lecture des fichiers de texture
**************************************************************************/

#include <gl.h>
#include <device.h>
#include <gl/image.h>
#include "types.h"
#include "macros.h"


bw_to_cpack(b,l,n, col)
register unsigned short *b;
register unsigned long *l;
register int n;
VECTOR	 col;
{
    while(n>=8) {
	l[0] = 0x00010101*b[0];
	l[1] = 0x00010101*b[1];
	l[2] = 0x00010101*b[2];
	l[3] = 0x00010101*b[3];
	l[4] = 0x00010101*b[4];
	l[5] = 0x00010101*b[5];
	l[6] = 0x00010101*b[6];
	l[7] = 0x00010101*b[7];
	col[0] += (float)((b[0]+b[1]+b[2]+b[3]+b[4]+b[5]+b[6]+b[7])/255.0);
	l += 8;
	b += 8;
	n -= 8;
    }
    while(n--) 
	col[0] += (float)(b[0]/255.0), *l++ = 0x00010101*(*b++);
}

rgb_to_cpack(r,g,b,l,n, col)
register unsigned short *r, *g, *b;
register unsigned long *l;
register int n;
VECTOR	 col;
{
    register int i;
    VECTOR	 local;

    while(n>=8) {
	l[0] = r[0] | (g[0]<<8) | (b[0]<<16);
	l[1] = r[1] | (g[1]<<8) | (b[1]<<16);
	l[2] = r[2] | (g[2]<<8) | (b[2]<<16);
	l[3] = r[3] | (g[3]<<8) | (b[3]<<16);
	l[4] = r[4] | (g[4]<<8) | (b[4]<<16);
	l[5] = r[5] | (g[5]<<8) | (b[5]<<16);
	l[6] = r[6] | (g[6]<<8) | (b[6]<<16);
	l[7] = r[7] | (g[7]<<8) | (b[7]<<16);
	for(i = 0; i < 8; i++)
	  {
	    V_init(local, (float)(r[i]/255.0),
		          (float)(g[i]/255.0),
		          (float)(b[i]/255.0));
	    V_add_self(col, local);
	  }
	l += 8;
	r += 8;
	g += 8;
	b += 8;
	n -= 8;
    }
    while(n--)
	{
	  V_init(local, (float)(r[0]/255.0),
		        (float)(g[0]/255.0),
		        (float)(b[0]/255.0));
	  V_add_self(col, local);
          *l++ = *r++ | ((*g++)<<8) | ((*b++)<<16);
	}
}

rgba_to_cpack(r,g,b,a,l,n, col)
register unsigned short *r, *g, *b, *a;
register unsigned long *l;
register int n;
VECTOR	 col;
{
    register int i;
    VECTOR	 local;

    while(n>=8) {
	l[0] = r[0] | (g[0]<<8) | (b[0]<<16) | (a[0]<<24);
	l[1] = r[1] | (g[1]<<8) | (b[1]<<16) | (a[1]<<24);
	l[2] = r[2] | (g[2]<<8) | (b[2]<<16) | (a[2]<<24);
	l[3] = r[3] | (g[3]<<8) | (b[3]<<16) | (a[3]<<24);
	l[4] = r[4] | (g[4]<<8) | (b[4]<<16) | (a[4]<<24);
	l[5] = r[5] | (g[5]<<8) | (b[5]<<16) | (a[5]<<24);
	l[6] = r[6] | (g[6]<<8) | (b[6]<<16) | (a[6]<<24);
	l[7] = r[7] | (g[7]<<8) | (b[7]<<16) | (a[7]<<24);
	for(i = 0; i < 8; i++)
	  {
	    V_init(local, (float)(r[i]/255.0),
		          (float)(g[i]/255.0),
		          (float)(b[i]/255.0));
	    V_add_self(col, local);
	  }
	l += 8;
	r += 8;
	g += 8;
	b += 8;
	a += 8;
	n -= 8;
    }
    while(n--) 
	{
	  V_init(local, (float)(r[0]/255.0),
		        (float)(g[0]/255.0),
		        (float)(b[0]/255.0));	  
	  V_add_self(col, local);
          *l++ = *r++ | ((*g++)<<8) | ((*b++)<<16) | ((*a++)<<24);
	}
}

unsigned long *load_image(char	    *name, 
                          int	    *size_x, 
			  int	    *size_y,
			  VECTOR    color)
{
    unsigned long *base, *lptr;
    short *rbuf, *gbuf, *bbuf, *abuf;
    IMAGE *image;
    int y;

    image = iopen(name,"r");
    if(!image) {
	fprintf(stderr,"load_image: can't open image file %s\n",name);
	return NULL;
    }
    (*size_x) = image->xsize;
    (*size_y) = image->ysize;

    base = (unsigned long *)
           malloc(image->xsize *image->ysize *sizeof(unsigned long));
    rbuf = (short *)malloc(image->xsize*sizeof(short));
    gbuf = (short *)malloc(image->xsize*sizeof(short));
    bbuf = (short *)malloc(image->xsize*sizeof(short));
    abuf = (short *)malloc(image->xsize*sizeof(short));
    if(!base || !rbuf || !gbuf || !bbuf) {
	fprintf(stderr,"load_image: can't malloc enough memory\n");
	exit(1);
    }

    lptr = base;
    V_null(color);

    for(y=0; y<image->ysize; y++) {
	if(image->zsize>=4) {
	    getrow(image,rbuf,y,0);
	    getrow(image,gbuf,y,1);
	    getrow(image,bbuf,y,2);
	    getrow(image,abuf,y,3);
	    rgba_to_cpack(rbuf,gbuf,bbuf,abuf,lptr,image->xsize, color);
	    lptr += image->xsize;
	} else if(image->zsize==3) {
	    getrow(image,rbuf,y,0);
	    getrow(image,gbuf,y,1);
	    getrow(image,bbuf,y,2);
	    rgb_to_cpack(rbuf,gbuf,bbuf,lptr,image->xsize, color);
	    lptr += image->xsize;
	} else {
	    getrow(image,rbuf,y,0);
	    bw_to_cpack(rbuf,lptr,image->xsize, color);
	    color[1] = color[2] = color[0];
	    lptr += image->xsize;
	}
    }
    V_scale(color, (1.0/(image->xsize*image->ysize)), color);
    iclose(image);
    free(rbuf);
    free(gbuf);
    free(bbuf);
    free(abuf);
    return base;
}

