Logo Search packages:      
Sourcecode: paul version File versions  Download package

paul.c

/*****************************************************************************
 *                                                                           *
 * Program:   paul                                                           *
 *            (P)rogramm zur (A)uswertung und (U)mformung von                *
 *            (L)aserbildern                                                 *
 * Uses:      GTK+ 1.2, Imlib, GtkImReg                                      *
 * Modul:     paul.c (main)                                                  *
 * Author:    Andreas Tille                                                  *
 * Date:      18.02.1998                                                     *
 * Copyright: Andreas Tille, 1999, 2000, 2001, 2002; GNU Public License      *
 *                                                                           *
 *****************************************************************************/

#include <gdk_imlib.h>
#include <gdk/gdk.h>
#include <gdk/gdkkeysyms.h>
#include <ctype.h>
#include <locale.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <X11/Xlib.h>

#include "paul.h"
#include "callback.h"
#include "names.h"

const    char *exename;
PAUL     paul;

int usage(void)
/* --- Return: ---
 * int  usage() : just RET_ERR
 */
{
  fprintf(stderr, _("Usage: %s [<option[s]>] [image-file[s]]\n"), exename);
  fputs(_("-a<[*c][+b]>:   change contr_A_st (*c) and brightness (+b)\n"), stderr);
  fputs(_("-b[file]:       calculate average _B_rightnesses of all images\n"), stderr);
  fputs(_("-c<wxh+x+y>:    _C_ut image of width w and height h at pixel (x,y) or\n"), stderr);
  fputs(_("  <a,b_c,d>:    area inbetween (a,b) and (c,d)\n"), stderr);     
  fputs(_("-d[e]:          _D_ifference image (suppress \"noise\" up to e)\n"), stderr);
  fputs(_("-e[ai]<a*b>:    search for _E_xtrema of brightness of size a*b\n"), stderr);
  fputs(_("                -ea = only m_A_xima; -ei = only m_I_nima\n"), stderr);
  fputs(_("-f[hvmM][i]:    median _F_ilter of order i (default: horizontal order 3)\n"), stderr);
  fputs(_("-g<a>[e]:       make color images _G_ray\n"), stderr);
  fputs(_("-h:             store _H_istogram in textfile\n"), stderr);
  fputs(_("-i[a]:          print _I_nformation about images (if a is given print Gamma curve too)\n"), stderr);
  fputs(_("-j[H]<a+b_file>[:url]: insert file at (a,b)\n"), stderr);
  fputs(_("                if `H` is given output HTML file with link to <url> if given\n"), stderr);
  fputs(_("-m              _M_ove images according to the first in image list.\n"), stderr);
  fputs(_("-n:             _N_egativ of image\n"), stderr);
  fputs(_("-o[PNG/TIFF]:   _O_utput of processed images in PNG or TIFF format (default PNG)\n"), 
        stderr);
  fputs(_("-p[hv]:         mirror _h_orizontal or _v_ertikal\n"), stderr);  
  fputs(_("-q:             _Q_uiet: no graphic display (useful for batch jobs)\n"), stderr);  
  fputs(_("-r[n][+s][-e]:  delete (black) bo_R_der / selection of real image information\n"),
        stderr);
  fputs(_("                n means delete only left and right but not top and bottom border\n"),
        stderr);
  fputs(_("                default: threshold for \"black\" [s] = 20\n"), stderr);
  fputs(_("                         allowed error for one pixel [e] = 50\n"), stderr);
  fputs(_("-s              delete (white) _S_canner border\n"), stderr);
  fputs(_("-t<d>           ro_T_ate d degrees clockwise (d = 90, 180, 270)\n"), stderr);
  fputs(_("-w[s]:          animate images with s seconds delay (default s=0).\n"), stderr);
  fputs(_("-z[i]           shrink i levels (1 level means = half the width and half the height)\n"),
        stderr);
  fputs(_("-F              calculate fast fourier transform of image\n"), stderr);
  fputs(_("-G              don't make _G_ray images green\n"), stderr);
  fputs(_("-H              print this _H_elp screen\n"), stderr);
  return RET_ERR;
}

static int PaulFailure(GList *piclist, char *msg)
/* free piclist and return errorcode, possibly print message
 */
{
  if ( msg ) g_warning(msg);
  FreePiclist(piclist);
  exit(RET_ERR);
}

int main(int argc, char **argv)
{
  PAUL           paul;
  OPTIONS        popt;
  int            i;                 /* counter for different purposes                        */
  register char *mp;                /* helping pointer                                       */
  GList         *pl;
  PICTURE       *bild;

  const char *cutorext;
  cutorext = _("Search for extrema and cut image isn't possible at the same time.");
  
  setlocale (LC_ALL, "");
  setlocale(LC_NUMERIC, "C");  /* to avoid strange number effects */
  
  bindtextdomain (PACKAGE, LOCALEDIR);
  textdomain (PACKAGE);
                 
  MessagesInit();
  PaulInitNames();
  
  exename       = strrchr (argv[0], '/');
  if (exename) ++exename;
  else           exename = argv[0];
  paul.id       = PAUL_ID;
  paul.piclist  = paul.spiclist = paul.activ   = NULL;
  paul.op       = NULL;
  paul.filelist = NULL;
  paul.show     = paul.w   = paul.ctrl = paul.opi = NULL;
  paul.items    = NULL;
#ifdef PHYSICAL_PAUL
  PG            = NULL;
  paul.curve    = NULL;
#endif
   
  popt.f      =  0;                 /* flag what to do with this garbage       */
  popt.cut    = NULL;               /* corners of area to cut                  */
  popt.eps    =  0;                 /* "noise step" for difference images      */
  popt.fordn  =  3;                 /* order of filtering                      */
  popt.filter =  0;                 /* type of filtering                       */
  popt.greps  =  255;               /* allowed difference between RGB values   */
  popt.shr    =  0;                 /* Stufe der Verkleinerungen               */ 
  popt.terr   =  DEFAULT_ERROR;     /* tollerierter Fehler für Randlöschen     */
  popt.thresh =  DEFAULT_THRESHOLD; /* Schwellwert für Randlöschen (-s)        */
  popt.offset =  0;                 /* offset for enhancing brightness         */
  popt.xi     =  popt.yi = -1;      /* coordinates for image to insert         */
  popt.bright = NULL;               /* no brightness file                      */
  popt.html   =  popt.link = NULL;  /* no HTML output and no link by default   */
  popt.angle  =  0.0;               /* rotation angle                          */
  popt.sek    = -1.0;               /* animation delay time between two images */
  popt.scale  =  1.0;               /* factor for contrast                     */
  /* if the program name is "gaul" turn gray images into green images for display */
  if ( strcmp(exename, "gaul") ) popt.f |= DISPLAYGRAY;

/*************************************************************************************
 * Read options                                                                      *
 *************************************************************************************/   
  while ( (i = getopt(argc, argv, "a:b::c:d::e:f::g::hi::j:mno::p:qr::st:w::z::FGH")) != EOF )
    switch (i) {
      case 'a': 
        { register char *pp;
          mp = strchr(optarg,'*');
          if ((pp = strchr(optarg,'+')) == NULL && mp == NULL ) return usage();
          if ( mp ) if ( sscanf(mp, "*%lg", &(popt.scale)) != 1 ) return usage();
          if ( pp ) {
            if ( sscanf(pp, "+%i", &i) != 1 ) return usage();
            else popt.offset = (unsigned char)i;
          }
        }
        break;
      case 'b': 
        popt.f |= BRIGHT;
        if ( !optarg ) popt.bright = g_strdup(BRIGHTFILE);
        else           popt.bright = g_strdup(optarg);
        break;
      case 'c': 
        if ( SaveExtrema(popt.f) ) {
           g_warning("%s%s", cutorext, _("Ignore cutting image."));
           break;
      }
        if ( !( popt.cut = ReadBoxFromString(optarg) ) ) return usage();
        break;
      case 'd': 
        popt.f |= DIFFERENZ;
        if ( !optarg ) break;
        if ( sscanf(optarg, "%i", &i) != 1 ) return usage();
        popt.eps = (unsigned char)i;
        break;
      case 'e':
        { register char *ap = optarg;
          if ( popt.cut ) {
          g_warning("%s%s", cutorext, _("Ignore search for extrema."));
            break;
          } 
          if ( toupper(*ap) == 'A' )      { popt.f |= SAVEMAXIMA; ap++; }
          else if ( toupper(*ap) == 'I' ) { popt.f |= SAVEMINIMA; ap++; }
               else                         popt.f |= SAVEEXTREMA;
          popt.cut = g_new(BOX, 1);
          if ( sscanf(ap, "%i*%i", &(popt.cut->x2), &(popt.cut->y2)) != 2 ) return usage();
          if ( popt.cut->x2 <= 0 || popt.cut->y2 <= 0 ) {
            g_warning(_("Invalid size of section: %i*%i"), popt.cut->x2, popt.cut->y2);
            return usage();
          }
        }
        break;
      case 'f': 
        if ( !optarg ) {
          popt.f     |= FILTER;
          popt.filter = 'h';
          break;
        }
        switch ( *optarg ) {
        case 'M' : popt.filter = 'M'; break;
        case 'm' : popt.filter = 'm'; break;
        case 'v' : popt.filter = 'v'; break;
        case 'h' : 
          default  : popt.filter = 'h'; break;
      }
      if ( (sscanf(optarg + (isdigit(*optarg)?0:1), "%i", &i)) != 1 ) popt.fordn = 3;
        else popt.fordn = (unsigned char)i;
        if ( popt.fordn < 3 || !(popt.fordn & 1) ) {
          g_warning(_("Invalid filter order %i. No filtering."), popt.fordn);
          popt.filter = 0;
            } else 
          popt.f     |= FILTER;
        break;
      case 'g': 
        popt.f |= MAKEGRAY;
        if ( !optarg ) popt.greps = 255;
        else { 
          register char *pp = optarg;
          switch ( *pp ) {
            case 'r': popt.greps = 0; break;
            case 'g': popt.greps = 1; break;
            case 'b': popt.greps = 2; break;
            case 'a': pp++; /* continue at default ! */
            default : popt.greps = 255; 
                      if ( sscanf(pp, "%i", &i) == 1 ) {
                        if ( (popt.greps = (unsigned char)i) < 3 ) {
                          g_warning(_("Set minimum eps to 3"));
                        popt.greps = 3;
                        }
                  }
        }
        }
        break;
      case 'h': 
        popt.f |= HISTOGRAMM;
        break;
      case 'i': 
        popt.f |= INFO;
        if ( optarg && *optarg == 'a' ) popt.f |= PRINTGAMMA;
        break;
      case 'j':
        { register char *ap = optarg, *bp;

          if ( *ap == 'H' ) {
            popt.f |= HTMLOUTPUT;
            ++ap;
          }
          if ( sscanf(ap, "%i+%i", &(popt.xi), &(popt.yi)) != 2 ) return usage();
          if ( !(ap = strchr(ap, '_')) || !*(++ap) ) return usage();
          if ( popt.xi < 0 || popt.yi < 0 ) {
            g_warning(_("Invalid coordinates to insert image: %i*%i"), popt.xi, popt.yi);
            return usage();
          }
          if ( HtmlOutput(popt.f) && (bp = strchr(ap, ':')) ) {
          *(bp++) = 0;
          if ( *bp ) popt.link = g_strdup(bp);
        }
        
          if ( !(pl = ReadPic(ap, NULL)) ) return usage();
          if ( !(paul.op = BILD(pl)) ) return usage();
          if ( (bild = BILD(pl = pl->next)) )
            for ( ; pl; bild = BILD(pl = pl->next) )
              paul.piclist = g_list_append(paul.piclist, bild);
        }
        break;
      case 'm':
        popt.f |= MATCHPICTURES;
        break;
      case 'n':
        popt.f |= NEGATIV;
        break;
      case 'o':
        if ( !optarg )                         SetPNG(popt.f);
        else if ( !strcasecmp(optarg, "TIF") ) SetTIFF(popt.f);
        else if ( !strcasecmp(optarg, "PNG") ) SetPNG(popt.f);
        else                                   g_warning(_("Unknown output format %s."), optarg);
        break;
      case 'p':
        if ( strchr(optarg,'h') ) popt.f |= MIRROR_H;
        if ( strchr(optarg,'v') ) popt.f |= MIRROR_V;
        if ( *optarg != 'h' && *optarg != 'v' ) return usage();
        break;
      case 'q':
        popt.f |= QUIET;
        break;
      case 'r':
        { register char *pp;
          /* reset default values */
          popt.f |= DELBORDER;
          if ( optarg ) {
            if ( (mp = strchr(optarg,'+')) != NULL ) {
              if ( sscanf(mp, "+%i", &i) != 1 ) return usage();
                popt.thresh = (unsigned char)i;
            }
            if ( (pp = strchr(optarg,'-')) != NULL ) {
              if ( sscanf(pp, "-%i", &i) != 1 ) return usage();
            popt.terr   = (unsigned char)i;
            }
            if ( strchr(optarg,'n') != NULL ) popt.f |= ONLYLEFTRIGHT;
          }
        }
        break;
      case 's':
        popt.f |= DELSCANBORDER;
        break;
      case 't':
        if ( !optarg || sscanf(optarg, "%lg", &(popt.angle)) != 1 ) return usage();
        while ( popt.angle >  360.0 ) popt.angle -= 360.0;
        while ( popt.angle <    0.0 ) popt.angle += 360.0;
        if      ( fabs(popt.angle -  90) < 1e-6 ) popt.f |= ROT_90;
        else if ( fabs(popt.angle - 180) < 1e-6 ) popt.f |= ROT_180;
        else if ( fabs(popt.angle - 270) < 1e-6 ) popt.f |= (ROT_90 | ROT_180);
        else popt.f |= ROTVAR;
        break;
      case 'w':
        if ( !optarg ) { popt.sek = 0; break; }
        if (sscanf(optarg, "%lg", &(popt.sek)) != 1) return usage();
        break;
      case 'z':
        popt.f |= SHRINK;
        if ( optarg == NULL ) break;
        if ( sscanf(optarg, "%i", &i) != 1 ) return usage();
        popt.shr = (unsigned char)i;  /* Mehr als 256 ist sinnlos */
        break;
      case 'F':
        popt.f |= FFT;
        break;
      case 'G':
        popt.f |= DISPLAYGRAY;
        break;
      case '?':
        g_warning("%s", optarg);
      case 'H':
      default:
        return usage();
    }
    /* Ende while(getopt()) */

/*************************************************************************************
 * Check for valid command line                                                      *
 *************************************************************************************/   
  if ( Differenz(popt.f) || DoMatchPictures(popt.f) ) {
    if ( argc - optind < 2 ) {
      g_warning(_("To build differences or to move images at least two files are necessary."));
      if ( popt.f & QUIET ) return RET_ERR;
      popt.f &= ~DIFFERENZ;
      popt.f &= ~MATCHPICTURES;
    }
  }

/*************************************************************************************
 * Read images                                                                       *
 *************************************************************************************/   
  paul.piclist = ReadPicFiles(paul.piclist, argc - optind, argv + optind, &popt);
  paul.opt = &popt;

  if ( !(paul.piclist) && (paul.opt->f & QUIET) ) {
    g_warning(_("No files preloaded")); 
    PaulExit(&paul);
  }

  if ( paul.piclist && (paul.opt->f || paul.opt->scale) ) {
/*************************************************************************************
 * Image manipulation                                                                *
 *************************************************************************************/   
    if ( Filter(paul.opt->f) && FilterBilder(&paul) == RET_ERR )
      PaulFailure(paul.piclist, NULL);

    if ( DoMakeGray(paul.opt->f) && MakeGray(&paul) == RET_ERR )
      PaulFailure(paul.piclist, NULL);

    if ( DelScanBorder(paul.opt->f) && DeleteScannerBorder(&paul) == RET_ERR ) 
      PaulFailure(paul.piclist, NULL);

    if ( DelBorder(paul.opt->f) && SelectPictureWithoutBorder(&paul) == RET_ERR) 
      PaulFailure(paul.piclist, NULL);

    if ( DoMatchPictures(paul.opt->f) && AutoMatchPictures(&paul) == RET_ERR ) 
      PaulFailure(paul.piclist, NULL);

    if ( Differenz(paul.opt->f) ) {               /* difference images     */
      if ( DifferenceQueue(&paul) == RET_ERR ) PaulFailure(paul.piclist, NULL);
    } else {
      if ( paul.opt->scale != 1.0 || paul.opt->offset != 0 )  /* Contrast and brightness */
        if ( SkaliereBilder(&paul) == RET_ERR ) PaulFailure(paul.piclist, NULL);
    }

    if ( SaveExtrema(paul.opt->f) &&  Extrema(&paul) == RET_ERR ) 
      PaulFailure(paul.piclist, NULL);

    if ( Negativ(paul.opt->f) && MakeNegative(paul.piclist) == RET_ERR )
      return PaulFailure(paul.piclist, NULL);

    if ( Mirror(paul.opt->f) && MakeMirror(&paul) == RET_ERR )
      return PaulFailure(paul.piclist, NULL);

    if ( Rotate(paul.opt->f) && MakeRotate(&paul) == RET_ERR )
      return PaulFailure(paul.piclist, NULL);

    if ( paul.opt->xi > -1 && InsertImage(&paul) == RET_ERR ) 
      return PaulFailure(paul.piclist, NULL); 
    if ( DoFFT(paul.opt->f) && FastFourierTransform(&paul) == RET_ERR ) 
      return PaulFailure(paul.piclist, NULL);

/*************************************************************************************
 * Analyse image                                                                     *
 *************************************************************************************/   
    if ( Bright(paul.opt->f) && AnalyseBrightness(&paul) == RET_ERR )
      return PaulFailure(paul.piclist, NULL);

    if ( HistogrammFlag(paul.opt->f) && (paul.opt->f & QUIET) ) 
      if ( PrintHistograms(paul.piclist) == RET_ERR ) return PaulFailure(paul.piclist, NULL);

/*************************************************************************************
 * Bildsicherung und -information                                                    *
 *************************************************************************************/   
    if ( Info(paul.opt->f) )                                    PaulInfo(paul.piclist, paul.opt->f);
      
    if ( paul.opt->f & QUIET ) {
      if ( SaveBild(paul.opt->f) ) SavePictures(paul.piclist, paul.opt->f);
      FreePiclist(paul.piclist);
      return RET_OK;
    }
  } /* end if ( files loaded and options given ) */
   
/*************************************************************************************
 * Bilddarstellung                                                                   *
 *************************************************************************************/
  { /* Test, if it is possible to open X-display */
    Display *display;
   
    if ( (display = XOpenDisplay(NULL)) ) XCloseDisplay(display);
    else if ( !paul.piclist ) {
      g_warning(_("Unable to open display"));
      usage();
      PaulExit(&paul);
    }
  }                           

  gtk_init(&argc, &argv);
  gdk_imlib_init();

  if ( paul.piclist ) {
    g_return_val_if_fail ( CreateShowPixmaps(paul.piclist) == RET_OK, RET_ERR );
    GtkInterface(&paul);
  } else 
    LoadFirstPicture(&paul);
   
  gtk_main();
  PaulExit(&paul);
  return RET_ERR;
}





Generated by  Doxygen 1.6.0   Back to index