////////////////////////////////////////////////////////////////////////////
/* 
nomarcas:  programa simple para eliminación de marcas de agua

Ismael Salvador 08/03/05

Este programa es Software Libre; usted puede redistribuirlo 
y/o modificarlo bajo los términos de la "GNU General Public
License" como lo publica la "FSF Free Software Foundation",
o (a su elección) de cualquier versión posterior.

Este programa es distribuido con la esperanza de que le será
útil, pero SIN NINGUNA GARANTIA; incluso sin la garantía
implícita por el MERCADEO o EJERCICIO DE ALGUN PROPOSITO en
particular. Vea la "GNU General Public License" para más
detalles.

Usted debe haber recibido una copia de la "GNU General Public
License" junto con este programa, si no, escriba a la "FSF
Free Software Foundation, Inc.", 59 Temple Place - Suite 330,
Boston, MA  02111-1307, USA.


This program is free software; you can redistribute it and/or 
modify it under the terms of the GNU General Public License as 
published by the Free Software Foundation; either version 2 of 
the License, or (at your option) any later version.

This program 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 General Public License for more details.

You should have received a copy of the GNU General Public 
License along with this program; if not, write to the Free 
Software Foundation, Inc., 59 Temple Place - Suite 330, 
Boston, MA 02111-1307, USA. 

*/
////////////////////////////////////////////////////////////////////////////


#include <stdio.h>
#include <stdlib.h>

#define TRUE  1
#define FALSE 0

// http://www-inst.eecs.berkeley.edu/cs160/sp05/section/6_color_design.ppt
// http://www.efg2.com/Lab/Graphics/Colors/HSV.htm
// http://www.normankoren.com/light_color.html
// http://www.codeproject.com/useritems/CPicker.asp
// http://www.efg2.com/Lab/Graphics/Colors/ColorRange.htm
// http://www.dcs.ex.ac.uk/~wmilne/graphics/standards.pdf
// http://www.cs.rit.edu/~ncs/color/t_convert.html
// http://answers.google.com/answers/threadview?id=68501

static void rgb_to_hsv(unsigned char r, unsigned char g, unsigned char b, int *h, int *s, int *v)
{
  unsigned char rgb[3];
  int min=255, max=0;
  int delta, i;
 
  rgb[0]=r; rgb[1]=g; rgb[2]=b;
  
  for (i=0; i < 3; i++) {
    if (rgb[i] > max) max=rgb[i];
    if (rgb[i] < min) min=rgb[i];
  }

  delta=max-min;

  *h = -1;  // undefined value for case where v outside [0,360]
  *v = max;
  *s = (max!=0) ? (255*delta/(float)max) : 0;
 
  if( *s != 0 ) {
    if     ( r==max )  *h = 60 * ((g-b)/(float)delta);
    else if( g==max )  *h = 60 * (2 + (b-r)/(float)delta);
    else if( b==max )  *h = 60 * (4 + (r-g)/(float)delta);
    //(*h) = (*h)*60;
    if( (*h) < 0 )  (*h)+=360;
  }
   
  //fprintf(stderr,"h %d s %d v %d\n",*h, *s, *v);
                                                                                                                           
 }

static int is_yellow_hsv(unsigned char red, unsigned char green, unsigned char blue){
  int h,s,v;
  int cond=FALSE;

  rgb_to_hsv(red,green,blue,&h,&s,&v);

  if (((h >  50) && (h < 75)) &&
      ((s > 100) && (s < 255)) &&
      ((v > 180) && (v < 255))) 
  cond=TRUE;

  return cond;
}

static int is_yellow_rgb(unsigned char red, unsigned char green, unsigned char blue){
  int cond=FALSE;
  
  if (((red - blue) > 89) && ((green - blue) > 89) && 
       (red > 125) && (green > 125) && 
	(((red-green) < 40) && ((red-green) > - 40))) cond=TRUE;

  //otra condicion seria |red-green| < 40 que no estén descompesados 

  //si es 255 no usar para hacer auto, satura

  //para auto probar hasta q no sature el azul

  return cond;
    
}

int remove_alpha(unsigned char **img, int cols, int rows, float alpha){
  int i,j,r,g,b;
  unsigned char red, green, blue;


  for(i = 0;i < rows;i++){
    for(j = 0;j < cols*3;j=j+3){
      red   = (*img)[i * cols * 3 + j];
      green = (*img)[i * cols * 3 + j + 1];
      blue  = (*img)[i * cols * 3 + j + 2];
      if (is_yellow_hsv(red, green, blue)){
        r = (int) (red   - (float)(1.0 - alpha)*255.0) / (float) alpha;
        g = (int) (green - (float)(1.0 - alpha)*255.0) / (float) alpha;
        b = (int) blue / (float) (1.0 - alpha);
       
        if (r < 0) r=0;
        if (g < 0) g=0;
        if (b > 255) b=255;

        (*img)[i * cols * 3 + j]     = r;
        (*img)[i * cols * 3 + j + 1] = g;
        (*img)[i * cols * 3 + j + 2] = b;

      }
    }                    
  }
}


void read_img(char *name, unsigned char **img, int *cols, int *rows){
  FILE *fd;
  char str[8];
  int binary,i, maxval;
  
  if ((fd=fopen(name,"r"))==NULL) {
    fprintf(stderr, "No puedo abrir %s\n",name);
  }

  //leo cabecera
  fscanf(fd,"%s\n",str);
  if (strcmp(str,"P3")==0) binary=0;
  else  binary=1;

  fscanf(fd,"%d %d\n",cols, rows);

  fscanf(fd,"%d\n", &maxval);
  
  *img = (unsigned char*)malloc((*cols) * (*rows) * 3 * sizeof(unsigned char));

  if (binary){
    //fprintf(stdout,"Leyendo binario\n");
    fread (*img, sizeof(unsigned char), (*cols)*(*rows) * 3, fd);
  }else{
    for(i=0;i<(*rows)*(*cols)*3;i++)
      fscanf(fd,"%u",(*img)[i]);
  }
  fclose(fd);
}

void save_img(char *name, unsigned char *img, int dcols, int drows, int channels, int binary){
  FILE *fd;
  int i,j;

  if ((fd=fopen(name,"w"))==NULL) {
    fprintf(stderr, "No puedo crear %s\n",name);
  }

  fprintf(stdout,"saving %s\n",name);

  if (binary == 0) {
    if (channels == 1)
      fprintf(fd,"P2\n");   
    else fprintf(fd,"P3\n"); 
  }
  
  else {
     if (channels == 1)
      fprintf(fd,"P5\n");   
     else fprintf(fd,"P6\n"); 
  }


  fprintf(fd,"%d %d\n255\n",dcols,drows);

  if (binary == 0){
    for(i = 0;i < drows; i++){
      for(j = 0; j < (dcols * channels) - 1; j++)
        fprintf(fd, "%d ",img[i * dcols * channels + j]);
      fprintf(fd, "%d\n",img[i * dcols * channels + j]);
    }
  }
  else {
    fwrite((const char *)img, 1,dcols * drows * channels, fd);
  }

  fclose(fd);
}



int main(int argc, char *argv[]) {

  char in[512], out[512];
  int cols, rows;
  unsigned char *img;
  float alpha;

  if (argc <= 1) {
    fprintf(stderr,"Necesito fichero de imagen\n");
    fprintf(stderr,"\nUso: %s imagen_in imagen_out [alpha]\n",argv[0]);
    exit(-1);
  }

  strcpy(in, argv[1]);
  strcpy(out, argv[2]);

  alpha=0.5;

  if (argc==4) {
    alpha=atof(argv[3]);
  } else
  fprintf(stdout,"alpha = %.1f\n",alpha);

  read_img(in, &img, &cols, &rows);
  remove_alpha(&img, cols, rows, alpha);
  save_img(out, img, cols,rows, 3, 1);

  free(img);
  exit(0);
}
