

/* PBMTOPTL.C:   Unix interface to splitAndMerge()     4/5/1993  */


#include "clarg.h"
#include "split-merge.h"

 
static char *USAGE =
  "\n%s:  Split and merge a binary image into a list of line segments (PTL).\n"
  "\n"
  "Arguments are:\n"
  "   -input file:          Specify the input file name (PBM)\n"
  "   -output file:         Specify the output file name (PTL)\n"
  "   -threshold t:         Specify threshold difference between actual\n"
  "                         pixels and approximating segment (default = 2.0).\n"
  "   -minlength l:         Minimum length segment to output (default = 2.0).\n"
  "   -comment:             Comment the output at the end of each component\n"
  "\n"
  "Warning:   increasing the threshold number of pixels will increase\n"
  "           the likelihood of creating crossing image edges in the\n"
  "           output.\n"
  "\n"
  "Argument names may be abreviated.  If no input file is specified,\n"
  "input is from stdin, and if no output file is specified, output\n"
  "is to stdout.\n\n";


#define INPUT 	"i.nput"
#define OUTPUT 	"o.utput"
#define THRESH	"t.hreshold"
#define MINLEN  "m.inlength"
#define COMMENT "c.omment"

static CLINIT clinit[] = {{INPUT,   1,  1, NULL,    0},
			  {OUTPUT,  1,  1, NULL,    0},
			  {THRESH,  1,  1, cl_real, 0},
			  {MINLEN,  1,  1, cl_real, 0},
                          {COMMENT, 0,  1, NULL,    0},
			  {NULL,    1,  1, NULL,    0}};


static char *depend[] = {"!(UNNAMED && "INPUT")", NULL};



int main(int argc, char **argv, char **envp)
{
  char *infile, *outfile;
  FILE *out;
  BinaryImage   image;
  SegmentVector segments;
  float         thresh;
  float         minlen;
  int i;
  short         comment = 0;
  

  if (cl_init(argc, argv, envp, clinit, depend, USAGE, CL_NORESTRICT))  /* parse args */
    return 0;

  infile  = (cl_opt(INPUT)
	     ? cl_arg1(INPUT)
	     : cl_opt(CL_UNNAMED) ? cl_arg1(CL_UNNAMED) : NULL);
  outfile = cl_opt(OUTPUT) ? cl_arg1(OUTPUT) : NULL;
  thresh  = cl_opt(THRESH) ? atof(cl_arg1(THRESH)) : 2.0;
  minlen  = cl_opt(MINLEN) ? atof(cl_arg1(MINLEN)) : 2.0;

  if (cl_opt(COMMENT)) {
    if (cl_numarg(COMMENT) == 0) {
      comment = SM_COMPONENT;
    }
    else {
      char *cs;

      for (cs = cl_arg1(COMMENT); *cs; cs++) {
        if (*cs == 'c')
          comment |= SM_COMPONENT;
        if (*cs == 'p')
          comment |= SM_PASS;
      }
    }
  }
  
  if ((image = (BinaryImage) imLoad(IMAGE_BINARY, infile)) == NULL) {
    fprintf(stderr, "PBMTOPTL:  Error reading image from %s\n",
	    infile ? infile : "<stdin>");
    return 0;
  }
  
  if ((segments = splitAndMerge(image, thresh, minlen, comment: comment)) == NULL) {
    fprintf(stderr, "PBMTOPTL:  Error from SplitAndMerge()\n");
    return 0;
  }

  if ((out = (outfile == NULL ? stdout : fopen(outfile, "w"))) == NULL) {
    fprintf(stderr, "PBMTOPTL:  Error opening output file \"%s\"\n", outfile);
    return 0;
  }

  fprintf(out, "\n\nPTL %d %d %d %d\n\n", imGetXBase(image),
	  imGetYBase(image), imGetWidth(image), imGetHeight(image));

  if (comment) {
    for (i = 0; i < vecUserData(segments).used; i++) {
      Segment seg = vecRef(segments, i);

      if (seg.a.x == seg.b.x  &&  seg.a.y == seg.b.y) {
        switch (seg.a.x) {
        case 0:
          fprintf(stdout, "\n# Component %d:\n", seg.a.y);
          break;
          
        case 1:
          fprintf(stdout, "\n#***** Pass %d *****\n", seg.a.y);
          break;
        }
      }
      else {
        fprintf(out, "l %d %d %d %d\n", seg.a.x, seg.a.y, seg.b.x, seg.b.y);
      }
    }
  }
  else {
    for (i = 0; i < vecUserData(segments).used; i++) {
      Segment seg = vecRef(segments, i);
      fprintf(out, "l %d %d %d %d\n", seg.a.x, seg.a.y, seg.b.x, seg.b.y);
    }
  }
  
  if (outfile)
    fclose(out);
  
  imFree(image);
  vecFree(segments);

  return 0;
}






