/* pbmminkowsky.c - read a portable bitmap and calculate the Minkowski Integrals
**
** Copyright (C) 2000 by Luuk van Dijk/Mind over Matter
**
** Based on pbmlife.c,
** Copyright (C) 1988,1 1991 by Jef Poskanzer.
**
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted, provided
** that the above copyright notice appear in all copies and that both that
** copyright notice and this permission notice appear in supporting
** documentation. This software is provided "as is" without express or
** implied warranty.
*/
#include "pbm.h"
#define ISWHITE(x) ((x) == PBM_WHITE)
int main(int argc, const char ** argv) {
FILE * ifP;
bit * prevrow;
bit * thisrow;
bit * tmprow;
int row;
int col;
int countTile;
int countEdgeX;
int countEdgeY;
int countVertex;
int rows;
int cols;
int format;
int area, perimeter, eulerchi;
pm_proginit(&argc, argv);
if (argc > 2)
pm_usage("[pbmfile]");
if (argc == 2)
ifP = pm_openr(argv[1]);
else
ifP = stdin;
pbm_readpbminit(ifP, &cols, &rows, &format);
prevrow = pbm_allocrow(cols);
thisrow = pbm_allocrow(cols);
/* first row */
pbm_readpbmrow(ifP, thisrow, cols, format);
countTile = 0;
countEdgeX = 0;
countEdgeY = 0;
countVertex = 0;
/* tiles */
for (col = 0; col < cols; ++col)
if (ISWHITE(thisrow[col]))
++countTile;
/* shortcut: for the first row, edgeY == countTile */
countEdgeY = countTile;
/* x-edges */
if (ISWHITE(thisrow[0]))
++countEdgeX;
for (col = 0; col < cols-1; ++col)
if (ISWHITE(thisrow[col]) || ISWHITE(thisrow[col+1]))
++countEdgeX;
if (ISWHITE(thisrow[cols-1]))
++countEdgeX;
/* shortcut: for the first row, countVertex == countEdgeX */
countVertex = countEdgeX;
for (row = 1; row < rows; ++row) {
tmprow = prevrow;
prevrow = thisrow;
thisrow = tmprow;
pbm_readpbmrow(ifP, thisrow, cols, format);
/* tiles */
for (col = 0; col < cols; ++col)
if (ISWHITE(thisrow[col]))
++countTile;
/* y-edges */
for (col = 0; col < cols; ++col)
if (ISWHITE(thisrow[col]) || ISWHITE(prevrow[col]))
++countEdgeY;
/* x-edges */
if (ISWHITE(thisrow[0]))
++countEdgeX;
for (col = 0; col < cols-1; ++col)
if (ISWHITE(thisrow[col]) || ISWHITE(thisrow[col+1]))
++countEdgeX;
if (ISWHITE(thisrow[cols-1]))
++countEdgeX;
/* vertices */
if (ISWHITE(thisrow[0]) || ISWHITE(prevrow[0]))
++countVertex;
for (col = 0; col < cols-1; ++col)
if (ISWHITE(thisrow[col]) || ISWHITE(thisrow[col+1])
|| ISWHITE(prevrow[col]) || ISWHITE(prevrow[col+1]))
++countVertex;
if (ISWHITE(thisrow[cols-1]) || ISWHITE(prevrow[cols-1]))
++countVertex;
} /* for row */
/* now thisrow contains the top row*/
/* tiles and x-edges have been counted, now y-edges and top
vertices remain
*/
/* y-edges */
for (col = 0; col < cols; ++col)
if (ISWHITE(thisrow[col]))
++countEdgeY;
/* vertices */
if (ISWHITE(thisrow[0]))
++countVertex;
for (col = 0; col < cols-1; ++col)
if (ISWHITE(thisrow[col]) || ISWHITE(thisrow[col+1]))
++countVertex;
if (ISWHITE(thisrow[cols-1]))
++countVertex;
/* cleanup */
pm_close(ifP);
/* print results */
printf(" tiles:\t%d\n x-edges:\t%d\n y-edges:\t%d\nvertices:\t%d\n",
countTile, countEdgeX, countEdgeY,countVertex);
area = countTile;
perimeter = 2*countEdgeX + 2*countEdgeY - 4*countTile;
eulerchi = countTile - countEdgeX - countEdgeY + countVertex;
printf(" area:\t%d\nperimeter:\t%d\n eulerchi:\t%d\n",
area, perimeter, eulerchi );
return 0;
}