/**************************************************************************
 * File: dissolve.c             DISSOLVE.C
 * Programmer: Justin Miller Cornell id# 356452
 * Project: Dissolve Detection
 *
 * Purpose: 
 * Limitations: 
 * This File: 
 *   -
 *   -
 * Last Sanity Check: never.
 *
 * ToDo: Make more stable.  Fix interface. 
 * 
 * Compile Time directives:
 *  - MULTIPROC - the multiple process version, uses shared memory to buffer
 *       results.
 *  - USING_GDB - turns off multiple process mode.
 *
 * See Also: 
 *
 * Copyright (c) 1995 Cornell University.  All Rights Reserved.
 *************************************************************************/


/* Feeble Explanation of what a typical usage should look like */
/* a stream consists of running:
 *  diss_storage_init()
 *  diss_first_frame(image000)
 *  for(i = 1 to max){
 *    diss_jnext_frame(image(i),compsPtr+i,"filename");
 *  }
 * diss_storage_free;
 */

/* ALL SORTS OF GOODIES TO INCLUDE*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include "misc.h"
#include "math.h"
#include "image.h"
#include "assert.h"
#include "solaris.h"
#include "routines.h"      /* pgm crop*/
#include "boxGaussian.h"   /* smoothing*/
#include "cannyEdge.h"     /* edge detection*/
#include "hausd_corr.h"    /* binary hausd*/
#include "utility.h"
#include "datafile.h"

/* TYPE DEFINITIONS*/

typedef struct {
  Quad q;
  GrayImage pgm;
  BinaryImage edges;
#ifndef NO_CENSUS
  ShortImage census;
#endif
  int threshold;
  int optThreshold;
} _Frame;

typedef _Frame *Frame;


/* MAGIC NUMBERS*/
/* General*/
#define HORZ_CORR       7
#define VERT_CORR       7
#define DILATE_DEFAULT  4
#define MODE_HELP       0
#define MODE_BINARY     1
#define MODE_DEFAULT    1

/* Image Smoothing Magic Numbers*/
#define NUM_BOXS             4
#define SIGMA_DEFAULT        1.2
#define THRESHOLD_DEFAULT    18      /* valid range is 0 - 255 */
#define DEFAULT_DESIREDP     0.03
#define DEFAULT_MINTHRESH    0
#define DEFAULT_MAXTHRESH   100

/* Thresholding images*/
#define THMODE_DEFAULT   0
#define THMODE_NONE      0
#define THMODE_ADAPT     1
#define THMODE_BACKADAPT 2

#define sanity(x,s) ({if(!(x)){fprintf(stderr,"SANITY ERROR: %s , in line %d of %s\n",(s),__LINE__,__FILE__);exit(-1);}})


/* Edge detection*/
#define EDGE_MODE_CANNY   0
#define EDGE_MODE_LAPLACE 1 
#define EDGE_MODE_CENSUS  2

/* PROTOTYPES FOR INTERNAL PROCEDURES*/
void edgeDetect(Frame newF);
double edgeThresher(comp *out, Frame prevF, Frame newF);
double edgeThreshFirst(Frame newF);
int calcThreshold(Quad q, double desiredP);
void killFrame(Frame f);
void saveEdges(BinaryImage edges, char *outname, char* tag);
void hausd_2d_NEWdecide(comp *out, double *forward, double *reverse,
			int rangeX, int rangeY, 
			int *rX, int *rY, int *direction);
void pbm_percentHalf(comp *curr, BinaryImage inim);

/* MACRO DEFINITIONS */
#define thresholdFrame(f,t) ({thresholdQuad((f)->q,(t));(f)->threshold=t;})
#define thresholdFrameNew(f,t)({(f)->edges=thresholdQuadNew((f)->q,(t));(f)->threshold=t;}) 

/* INTERFACE MACROS*/

/* GLOBAL VARIABLES*/
/* none of these global variables needs to be set for compare images to work */
/* correctly */
extern int    dilateDist  ;
extern double sigma       ;
extern int    threshold   ;
extern double desiredP    ;

extern int edgeDetectMode;
extern char *edgeDirName;
extern int edgeOutput;

extern int threshMode;
extern int threshModeCval;

extern int quickMode;
extern float quickModeCutoff;

extern unsigned char verbal;
extern int inOut;
#ifndef NO_DIFFPGM
extern GrayImage diffPGM;
extern int calcDiffPGM;
#endif
#ifndef NO_TWOPASS
extern int useTwoPasses;
#endif
#ifndef NO_RESOLVE_EDGES
extern int useResolveEdges;
#endif
#ifndef NO_CENSUS
extern int useCensus;
#endif


char *diss_version(void);
void diss_storage_init(int dx, int dy, int width, int height);
void diss_storage_free(void);
void diss_first_frame(GrayImage gimage);
void diss_next_frame(GrayImage gimage, comp *compPtr, char* newname);

/* Explanation */
/* a stream consists of running:
 *  diss_storage_init()
 *  diss_first_frame(image000)
 *  for(i = 1 to max){
 *    diss_jnext_frame(image(i),compsPtr+i,"filename");
 *  }
 * diss_storage_free;
 */
