Blame analyzer/pgmminkowski.c

Packit 78deda
/* pgmminkowsky.c - read a portable graymap and calculate the Minkowski 
Packit 78deda
** Integrals as a function of the threshold.
Packit 78deda
**
Packit 78deda
** Copyright (C) 2000 by Luuk van Dijk/Mind over Matter
Packit 78deda
**
Packit 78deda
** Based on pgmhist.c, 
Packit 78deda
** Copyright (C) 1989 by Jef Poskanzer.
Packit 78deda
**
Packit 78deda
** Permission to use, copy, modify, and distribute this software and its
Packit 78deda
** documentation for any purpose and without fee is hereby granted, provided
Packit 78deda
** that the above copyright notice appear in all copies and that both that
Packit 78deda
** copyright notice and this permission notice appear in supporting
Packit 78deda
** documentation.  This software is provided "as is" without express or
Packit 78deda
** implied warranty.
Packit 78deda
*/
Packit 78deda
Packit 78deda
#include "pgm.h"
Packit 78deda
#include "mallocvar.h"
Packit 78deda
Packit 78deda
Packit 78deda
#define MAX2(a,b) ( ( (a)>(b) ) ? (a) : (b) )
Packit 78deda
#define MAX4(a,b,c,d) MAX2( MAX2((a),(b)), MAX2((c),(d)) )
Packit 78deda
Packit 78deda
int main( int argc, char** argv ){
Packit 78deda
  
Packit 78deda
  FILE *ifp;
Packit 78deda
Packit 78deda
  gray maxval;
Packit 78deda
  int cols, rows, format;
Packit 78deda
Packit 78deda
  gray* prevrow;
Packit 78deda
  gray* thisrow;
Packit 78deda
  gray* tmprow;
Packit 78deda
  
Packit 78deda
  int* countTile;   
Packit 78deda
  int* countEdgeX;  
Packit 78deda
  int* countEdgeY; 
Packit 78deda
  int* countVertex; 
Packit 78deda
Packit 78deda
  int i, col, row;
Packit 78deda
Packit 78deda
  int maxtiles, maxedgex, maxedgey, maxvertex;
Packit 78deda
  int area, perimeter, eulerchi;
Packit 78deda
Packit 78deda
  double l2inv, linv;
Packit 78deda
Packit 78deda
  /*
Packit 78deda
   * parse arg and initialize
Packit 78deda
   */ 
Packit 78deda
Packit 78deda
  pgm_init( &argc, argv );
Packit 78deda
Packit 78deda
  if ( argc > 2 ) pm_usage( "[pgmfile]" );
Packit 78deda
  
Packit 78deda
  if ( argc == 2 )
Packit 78deda
    ifp = pm_openr( argv[1] );
Packit 78deda
  else
Packit 78deda
    ifp = stdin;
Packit 78deda
Packit 78deda
  /*
Packit 78deda
   * initialize
Packit 78deda
   */
Packit 78deda
Packit 78deda
  pgm_readpgminit( ifp, &cols, &rows, &maxval, &format );
Packit 78deda
  
Packit 78deda
  prevrow = pgm_allocrow( cols );
Packit 78deda
  thisrow = pgm_allocrow( cols );
Packit 78deda
  
Packit 78deda
  MALLOCARRAY(countTile   , maxval + 1 );
Packit 78deda
  MALLOCARRAY(countEdgeX  , maxval + 1 );
Packit 78deda
  MALLOCARRAY(countEdgeY  , maxval + 1 );
Packit 78deda
  MALLOCARRAY(countVertex , maxval + 1 );
Packit 78deda
 
Packit 78deda
  if (countTile == NULL || countEdgeX == NULL || countEdgeY == NULL ||
Packit 78deda
      countVertex == NULL)
Packit 78deda
      pm_error( "out of memory" );
Packit 78deda
  
Packit 78deda
  for ( i = 0; i <= maxval; i++ ) countTile[i]   = 0;
Packit 78deda
  for ( i = 0; i <= maxval; i++ ) countEdgeX[i]  = 0;
Packit 78deda
  for ( i = 0; i <= maxval; i++ ) countEdgeY[i]  = 0;
Packit 78deda
  for ( i = 0; i <= maxval; i++ ) countVertex[i] = 0;
Packit 78deda
Packit 78deda
Packit 78deda
Packit 78deda
Packit 78deda
  /* first row */
Packit 78deda
Packit 78deda
  pgm_readpgmrow( ifp, thisrow, cols, maxval, format );
Packit 78deda
Packit 78deda
  /* tiles */
Packit 78deda
Packit 78deda
  for ( col = 0; col < cols; ++col ) ++countTile[thisrow[col]]; 
Packit 78deda
  
Packit 78deda
  /* y-edges */
Packit 78deda
Packit 78deda
  for ( col = 0; col < cols; ++col ) ++countEdgeY[thisrow[col]]; 
Packit 78deda
Packit 78deda
  /* x-edges */
Packit 78deda
Packit 78deda
  ++countEdgeX[thisrow[0]];
Packit 78deda
Packit 78deda
  for ( col = 0; col < cols-1; ++col ) 
Packit 78deda
    ++countEdgeX[ MAX2(thisrow[col], thisrow[col+1]) ];
Packit 78deda
  
Packit 78deda
  ++countEdgeX[thisrow[cols-1]];
Packit 78deda
  
Packit 78deda
  /* shortcut: for the first row, countVertex == countEdgeX */
Packit 78deda
  
Packit 78deda
  ++countVertex[thisrow[0]];
Packit 78deda
Packit 78deda
  for ( col = 0; col < cols-1; ++col ) 
Packit 78deda
    ++countVertex[ MAX2(thisrow[col], thisrow[col+1]) ];
Packit 78deda
Packit 78deda
  ++countVertex[thisrow[cols-1]];
Packit 78deda
Packit 78deda
  
Packit 78deda
Packit 78deda
  for ( row = 1; row < rows; ++row ){  
Packit 78deda
    
Packit 78deda
    tmprow = prevrow; 
Packit 78deda
    prevrow = thisrow;
Packit 78deda
    thisrow = tmprow;
Packit 78deda
 
Packit 78deda
    pgm_readpgmrow( ifp, thisrow, cols, maxval, format );
Packit 78deda
  
Packit 78deda
    /* tiles */
Packit 78deda
Packit 78deda
    for ( col = 0; col < cols; ++col ) ++countTile[thisrow[col]]; 
Packit 78deda
    
Packit 78deda
    /* y-edges */
Packit 78deda
    
Packit 78deda
    for ( col = 0; col < cols; ++col ) 
Packit 78deda
      ++countEdgeY[ MAX2(thisrow[col], prevrow[col]) ];
Packit 78deda
    /* x-edges */
Packit 78deda
    
Packit 78deda
    ++countEdgeX[thisrow[0]];
Packit 78deda
    
Packit 78deda
    for ( col = 0; col < cols-1; ++col ) 
Packit 78deda
      ++countEdgeX[ MAX2(thisrow[col], thisrow[col+1]) ];
Packit 78deda
    
Packit 78deda
    ++countEdgeX[thisrow[cols-1]];
Packit 78deda
    
Packit 78deda
    /* vertices */
Packit 78deda
Packit 78deda
    ++countVertex[ MAX2(thisrow[0],prevrow[0]) ];
Packit 78deda
Packit 78deda
    for ( col = 0; col < cols-1; ++col ) 
Packit 78deda
      ++countVertex[
Packit 78deda
        MAX4(thisrow[col], thisrow[col+1], prevrow[col], prevrow[col+1])
Packit 78deda
      ];
Packit 78deda
    
Packit 78deda
    ++countVertex[ MAX2(thisrow[cols-1],prevrow[cols-1]) ];
Packit 78deda
    
Packit 78deda
  } /* for row */
Packit 78deda
  
Packit 78deda
  /* now thisrow contains the top row*/
Packit 78deda
Packit 78deda
  /* tiles and x-edges have been counted, now upper
Packit 78deda
     y-edges and top vertices remain */
Packit 78deda
  
Packit 78deda
  /* y-edges */
Packit 78deda
Packit 78deda
  for ( col = 0; col < cols; ++col ) ++countEdgeY[ thisrow[col] ];
Packit 78deda
Packit 78deda
  /* vertices */
Packit 78deda
  
Packit 78deda
  ++countVertex[thisrow[0]];
Packit 78deda
Packit 78deda
  for ( col = 0; col < cols-1; ++col ) 
Packit 78deda
    ++countVertex[ MAX2(thisrow[col],thisrow[col+1]) ];
Packit 78deda
Packit 78deda
  ++countVertex[ thisrow[cols-1] ];
Packit 78deda
Packit 78deda
Packit 78deda
  /* cleanup */
Packit 78deda
Packit 78deda
  maxtiles =  rows    * cols;
Packit 78deda
  maxedgex =  rows    * (cols+1);
Packit 78deda
  maxedgey = (rows+1) *  cols;
Packit 78deda
  maxvertex= (rows+1) * (cols+1);
Packit 78deda
  
Packit 78deda
  l2inv = 1.0/maxtiles;
Packit 78deda
  linv  = 0.5/(rows+cols);
Packit 78deda
Packit 78deda
  /* And print it. */
Packit 78deda
  printf( "#threshold\t tiles\tx-edges\ty-edges\tvertices\n" );
Packit 78deda
  printf( "#---------\t -----\t-------\t-------\t--------\n" );
Packit 78deda
  for ( i = 0; i <= maxval; i++ ){
Packit 78deda
Packit 78deda
    if( !(countTile[i] || countEdgeX[i] || countEdgeY[i] || countVertex[i] ) ) 
Packit 78deda
      continue; /* skip empty slots */
Packit 78deda
Packit 78deda
    area      = maxtiles;
Packit 78deda
    perimeter = 2*maxedgex + 2*maxedgey - 4*maxtiles;
Packit 78deda
    eulerchi  = maxtiles - maxedgex - maxedgey + maxvertex;
Packit 78deda
Packit 78deda
    printf( "%f\t%6d\t%7d\t%7d\t%8d\t%g\t%g\t%6d\n", (float) i/(1.0*maxval), 
Packit 78deda
        maxtiles, maxedgex, maxedgey, maxvertex,
Packit 78deda
        area*l2inv, perimeter*linv, eulerchi
Packit 78deda
        );
Packit 78deda
Packit 78deda
Packit 78deda
    maxtiles -= countTile[i];
Packit 78deda
    maxedgex -= countEdgeX[i];
Packit 78deda
    maxedgey -= countEdgeY[i];
Packit 78deda
    maxvertex-= countVertex[i];
Packit 78deda
Packit 78deda
    /*  i, countTile[i], countEdgeX[i], countEdgeY[i], countVertex[i] */
Packit 78deda
Packit 78deda
  }
Packit 78deda
Packit 78deda
  /* these should be zero: */
Packit 78deda
  printf( "#  check:\t%6d\t%7d\t%7d\t%8d\n", 
Packit 78deda
          maxtiles, maxedgex, maxedgey, maxvertex );
Packit 78deda
Packit 78deda
  pm_close( ifp );
Packit 78deda
  
Packit 78deda
  exit( 0 );
Packit 78deda
  
Packit 78deda
} /*main*/
Packit 78deda
Packit 78deda