/*****************
* Programme appel par Compo pour faire un traitement statistique sur l'image
* bas sur la version de Jim
*  Jim Lesurf
* version pouvant recevoir des paramtres en provenance du script.
* sans OSLib
* The readpixel function works on a RGB picture whicj is in Compo memory
*  DeTox with Params version 01
*/



/* get image colour stats */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <stdarg.h>
#include "wimp.h"
#include "kernel.h"
#include "swis.h"

/* Other header files. */
//#include "oslib/os.h"
//#include "oslib/osspriteop.h"


unsigned int spriteareastart;
unsigned int firstsprite;
int *spritepointer;
unsigned int spritedata;
int height,width;
char *envpointer;
char rgbpointer;
char envstring[256];
char *charpointer;

int rhist[256];
int bhist[256];
int ghist[256];


FILE *outfile;

FILE *accufile;

FILE *gainfile;

double r,a,as,w,x,y,xo,yo,xd,yd,wd,f,w2pi;

double v,v2,w2,r2,e;

double racc,bacc,gacc;

// new
float bminpc = 0.01;
float bmaxpc = 50.0;
char FileNameTemp[256]; // to build path for stats files
char spritename[64];
// end new

int i,p,ncenter,n,nc,range,npixels;

int min_expanded, max_expanded;

int expanded_level[256];

double slope;

_kernel_swi_regs rin,rout;


// function prototypes
int get_sprite_start(void);
void get_sprite_size(void);
void get_sprite_name(void);
/* void draw_stuff(void); */

void read_pixels(void);
void read_sprite(void);

int thispixel(int,int);

static void fail(char *errmsg, ...)
{
    va_list ap;

    va_start(ap, errmsg);
    vfprintf(stderr, errmsg, ap);
    va_end(ap);
    exit(1);
}


/**********  main program  *******/
int main(int argc, char *argv[])
{
  // get arguments  :
  
  // argv[0] = appli name
  // argv[1] = selected imagebase pointer ?
  // argv[2] = bminpc,  argv[3] = bmaxpc
   if (argc != 4)
     fail("Usage: <.selected.imagebase> <bminpc> <bmaxpc>, argc= %d", argc );

   // get bminpc and bmaxpc
   bminpc = atoi(argv[2]);
   bmaxpc = atoi(argv[3]);
          
   // load sprite      
   i=0;
   do
   {
     rhist[i]=0; ghist[i]=0;; bhist[i]=0;
     i++;
   } while (i<255);
   
   racc = 0.0; gacc = 0.0; bacc =0.0;
  
   spriteareastart=get_sprite_start();
   get_sprite_size();
   get_sprite_name();
  //printf("sprite size: w = %d",width);
  //return 1;

  ncenter = width*height/2 + width/2; npixels = width*height;

  // new to ahve a different name for each picture
  // add sprite name to filename. 
  //outfile = fopen("RAM::RamDisc0.$.rgbout","w+");
  //accufile = fopen("RAM::RamDisc0.$.accufile","w+");
  //gainfile = fopen("RAM::RamDisc0.$.gainfile","w+");
  sprintf(FileNameTemp,"%s_%s", "RAM::RamDisc0.$.rgbout",spritename);
  outfile = fopen(FileNameTemp,"w+");
  sprintf(FileNameTemp,"%s_%s", "RAM::RamDisc0.$.accufile",spritename);
  accufile = fopen(FileNameTemp,"w+");
  sprintf(FileNameTemp,"%s_%s", "RAM::RamDisc0.$.gainfile",spritename);
  gainfile = fopen(FileNameTemp,"w+");
  read_pixels();
  
  return 0;
}

// not used
void greyscale_image(void)
{
  
  
}


/**
 * Read and get stat for picture
 * Then mofies the picture 
*/
void read_pixels(void)
{
  //int x,y;
  int pt;
  unsigned int colour;
  //unsigned int r,g,b,ro,bo,go,n,m, mo;
  unsigned int xstart,xstop;
  //unsigned int ystart,ystop;
  //unsigned int yc,xc;
  spritepointer=(int*)firstsprite;
  spritedata=firstsprite+spritepointer[8];
  spritepointer=(int*)spritedata;
  
  double rpc, gpc, bpc;
  unsigned int red,blue,green;
  //unsigned int greyout;
  
  double min, max;
  
  double slope;
  
  min = -1.0; max = -1.0;
  
  xstart=1; pt=0;
  xstop=width*height;
  
  pt=0;
  
  do
  {
    colour=spritepointer[pt];
    
    red = (colour >> 0) & 0xffu;
    green = (colour >> 8) & 0xffu;
    blue = (colour >> 16) & 0xffu;
    
    bhist[blue] = bhist[blue]+1;
    ghist[green] = ghist[green]+1;
    rhist[red] = rhist[red]+1;
    
    /* test line follows */
    
    /* */
    
    min_expanded = -1;  max_expanded = -1;
     
    pt += 1;
  } while (pt < npixels);
  
  pt=0;
     
     do
     { 
       rpc = 100.0*(double)rhist[pt];  rpc = rpc/(double)npixels;
       bpc = 100.0*(double)bhist[pt];  bpc = bpc/(double)npixels;
       gpc = 100.0*(double)ghist[pt];  gpc = gpc/(double)npixels;
       
       racc += rpc; bacc += bpc; gacc += gpc;
                                              
       if (min_expanded < 0)
       {
         //if (bacc > 0.1)
         if (bacc > bminpc)
         {
           min_expanded = pt;
           //printf ("min percent limit at %i\n", min_expanded);
         }
       }
       
       
       if (max_expanded < 0)
       {
         //if (bacc > 50.0)
         if (bacc > bmaxpc)
         {
           max_expanded = pt;
           //printf ("max percent limit at %i\n", max_expanded);
         }
       }
       
       
       fprintf(outfile,"%d, %7.3lf, %7.3lf, %7.3lf \n",(int)pt, rpc,gpc,bpc);

       fprintf(accufile,"%d, %7.3lf, %7.3lf, %7.3lf \n",(int)pt, racc,gacc,bacc);
       
       pt += 1;
     } while (pt < 256);
     
     
     
     slope = 255.0/(double)(max_expanded - min_expanded);
     
     
     pt = 0;
     
     do
     {
       
       expanded_level[pt] = 0;
      
       pt += 1;
     } while (pt <= min_expanded);
     
     do
     {
       expanded_level[pt] = (int) ( slope * (double)( pt - min_expanded)   );
       
       pt += 1;
     } while (pt <= max_expanded);
     
     do
     {
       expanded_level[pt] = 255;
       pt += 1;
     } while (pt <256);
     
     
    pt=0;
    
    do
    {
      fprintf( gainfile,"%i,  %i\n",pt, expanded_level[pt]);
      pt+=1;
    } while (pt < 256);
       
    /* now process image */
    
    pt = 0; 
    
    do
    {
      colour=spritepointer[pt];
    
    
      blue = (colour >> 16) & 0xffu;
      
      blue = expanded_level[blue];
      
      spritepointer[pt] = (unsigned int)( blue + blue*256 + blue*256*256); 
      
      pt += 1;
    } while (pt < width*height);
     
     fclose(outfile);  fclose(accufile); fclose(gainfile);
} 


int thispixel(int xin,int yin)
{
  int nout;
  nout = xin - yin*width + ncenter;
  return nout;
}

void get_sprite_name(void)
{
  spritepointer=(int*)spriteareastart;
  //firstsprite=spriteareastart+spritepointer[2];
  //sprintf(spritename,"%s",firstsprite);
  rin.r[0]=512+13;
  rin.r[1]=spriteareastart;
  rin.r[2]= (int)spritename;
  rin.r[3]= 256;
  rin.r[4]= 1;
  _kernel_swi(OS_SpriteOp,&rin,&rout);
  // debug
  // fail("sprite ptr %s", spritename);


}

void get_sprite_size(void)
{
  /*  Finds the width and height of the sprite  */
      
  spritepointer=(int*)spriteareastart;
  firstsprite=spriteareastart+spritepointer[2];
  rin.r[0]=512+40;
  rin.r[1]=spriteareastart;
  rin.r[2]=firstsprite;
  _kernel_swi(OS_SpriteOp,&rin,&rout);
  
  width=rout.r[3];
  height=rout.r[4];
  
 // printf( "width %d  height %d\n",width,height);
}

int get_sprite_start(void)
{
  int string_length;
  /* Reads environment string and gets first value
     as the integer sprite start address */
  
  _kernel_swi(OS_GetEnv,&rin,&rout);
  envpointer=(char*)rout.r[0];
  string_length=strlen(envpointer);
  strcpy(envstring,envpointer);
  
  i=(int)strchr(envstring,' ');
  return atoi((char*)i);
}
