/*  
    Copyright (C) 2003 Johan Borg

    This file is part of xmerge.

    xmerge 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.
                
    xmerge 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 xmerge; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include <stdio.h>
#include <sys/time.h>
#include <X11/Xlib.h>
#include <stdlib.h>
#include <fcntl.h>
#define __USE_ISOC99 1
#include <math.h>
#include <unistd.h>
#include <X11/Xutil.h>
#include <signal.h>
#include <sys/wait.h>
#include <string.h>
#include <strings.h>
#include <X11/cursorfont.h>

typedef struct pixt {
 unsigned char R,G,B;
} __attribute__ ((packed)) pixt; 


typedef struct linkp {
 struct IMG * si,*di;
 double sx1,sy1,sx2,sy2; //source, rewriting this to pos+size, might be advantagous
 double dx,dy;		//destination 
 int type,stat;
 double angle;
 XImage* ximg;	
} linkp;

typedef struct edget {
 int x,y,stat;
 double X,Y,t1,t2;
 struct edget *prev,*next;
} edget;


typedef struct IMG {
 int sx,sy,sd,Tx,Ty;			//size x,y,data
 double dx1,dx2,dy1,dy2;	//destination coordinates
 double dx3,dx4,dy3,dy4;
 int stat;
 double a,b,c,d,e,f,g,h;
 double p[8];
 double Gr,Gg,Gb;
 int Grn,Ggn,Gbn;
 int edgen;
// unsigned int cs;		//sum of all pixels, for debugging purposes only
 edget *edge;
 char * name;
 struct pixt pix[0];		//the image
} IMG;





/*
#define pG 2.0		//pH*pG=4 results in a truncation error of 0.018, with no visible degradation even in rather extreme cases, but for images with >8bpp, a product of 6 is probbably desireable
//filtering, lower is less, 2 is good

#define pH 2.5		//1 is not enough, 4 is too much.., 

//far truncation limit (end of table)
#define pT 2.0		//(times larger than the near limit
//length of the table
//#define pE 65536.0
#define pE 4096.0	//a smaller table will leave more L1/L2 cache avalible for caching the image
//NOTE: 4096 is hardcoded in some places 
#define pL 1.0		//minimum scaling allowed, if this is <1, the near limit needs to be increased
*/


//a new set... while using pG=1 result in severe truncation of the gaussian, it also improve sharpness when no scaling is required
#define pG 1.0		//pH*pG=4 results in a truncation error of 0.018, with no visible degradation even in rather extreme cases, but for images with >8bpp, a product of 6 is probbably desireable
#define pH 2.7		//1 is not enough, 4 is too much..
#define pT 1.0		//(times larger than the near limit
#define pE 4096.0	//a smaller table will leave more L1/L2 cache avalible for caching the image
#define pL 1.0		//minimum scaling allowed, if this is <1, the near limit needs to be increased


















//is the format we enter the margins in ok? would a list of nonconstant alpha - zones be better?
//or should we use determine the inner margin start from the overlapping margin end?
//we'll have to ignore the overlap from the oposite corner, when 4 sources meet at one point...

#define MAXMATCH 50			//max size of the matching region
#define MINMATCH 5			//min size ...
#define MAXLINKS 128			
#define SEARCH_SIZE 8			//large is slow and increase the possibility of bad locks, but too small will be inconvenient...
#define zoommax 8			//largest allowed zoom

extern IMG **simg;			//source images 
extern struct linkp rlink[MAXLINKS]; 	//linked points of images
extern int Ox,Oy,Ot;
extern int Mt,Mb,Ml,Mr;
extern int Mt0,Mb0,Ml0,Mr0;

IMG * read_ppm(char *name);
void write_ppm(IMG *img,char *name);
void write_mfile();

void mapcupd(IMG * img,double *x,double *y);
void mapc(IMG * img,double x,double y,double * nx,double * ny);
inline void mapcr(IMG * img,double X,double Y,double * nx,double * ny,double * dxx,double * dxy,double * dyx,double * dyy);
void solve();
void imapx_near(unsigned char * dest,int dx,int tx2,int ty2,double *x,double *y,IMG *img);
void mline(unsigned char * Data,int Dxl,int Dyl,int x1,int y1,int x2,int y2,unsigned int f,unsigned int b);
inline void mapcrs(IMG * img,double X,double Y,double * nx,double * ny);
void display_ximg2(int d,int x,int y);
void writed_ppm(unsigned char * data,int dx,int dy,char *name);
//void imap_ewa_merge(char * name);
void imap_ewa_merge(int ml,int mt,int mr,int mb,int fd);
void update_edges();
void imapx(unsigned char * dest,int dx,int dy,int dxo,int dyo,int zoom,IMG *img);
inline int ewa_pixel(IMG *img,double x,double y,double * CR,double *CG,double *CB,double *W);
int read_list(char *name);
void write_list(char *name);
edget * edge_add(IMG *img,edget *pos,int x,int y);
void read_files(char ** argv,int argc);
void run_gui();
int check_abort();
