// // pgmiso.cxx // // Generates a set of isolines from a portable grey map (or PGM) file. // Limitations: PGM must be binary, not ascii, and maxval should be 255, // which means an 8 bit greyscale. You can force a maxval with the // pnmdepth utility. For more info on PGM, see the NetPBM package. // // There are no dependencies, simply build with: // c++ -o pgmiso pgmiso.cxx // // Copyright by Bram Stolk, bram at sara.nl // Licensed under the Gnu Public License, or GPL. // See gnu.org website for more information on this license. // #include #include #include #include static void drawline(unsigned char *dstimg, int w, int h, unsigned char col[3], int x0, int y0, int x1, int y1) { int dx=0; int dy=0; if (x1x0) dx=1; if (y1y0) dy=1; do { memcpy(dstimg+3*x0+3*y0*w, col, 3); x0 += dx; y0 += dy; } while (x0 != x1 || y0 != y1); memcpy(dstimg+3*x0+3*y0*w, col, 3); } int main(int argc, char *argv[]) { if (argc!=4) { fprintf(stderr,"Usage: %s nr-of-isolines input.pgm output.ppm\n", argv[0]); exit(1); } int isocnt = atoi(argv[1]); FILE *f = fopen(argv[2],"rb"); assert(f); int w,h,maxval; char ws; int retval=fscanf(f,"P5 %d %d %d%c",&w,&h,&maxval,&ws); assert(retval==4); assert(maxval==255); unsigned char *srcimg = new unsigned char [w*h]; retval=fread(srcimg, w*h, 1, f); assert(retval==1); fclose(f); int step=4; int hstep=step/2; unsigned char *dstimg = new unsigned char [w*h*3]; // Copy the source image to the destination image. // You may want to skip this if you want the isolated isolines only, // without the original greyscale image in the background. unsigned char *reader = srcimg; unsigned char *writer = dstimg; for (int i=0; i isoval) b |= 1; if (srcimg[xx+y*w] > isoval) b |= 2; if (srcimg[x+yy*w] > isoval) b |= 4; if (srcimg[xx+yy*w] > isoval) b |= 8; if (b==0 || b==15) { } if (b==1 || b==14) { drawline(dstimg, w, h, col, x+hstep, y, x, y+hstep); } if (b==2 || b==13) { drawline(dstimg, w, h, col, x+hstep, y, x+step, y+hstep); } if (b==3 || b==12) { drawline(dstimg, w, h, col, x, y+hstep, x+step, y+hstep); } if (b==4 || b==11) { drawline(dstimg, w, h, col, x, y+hstep, x+hstep, y+step); } if (b==5 || b==10) { drawline(dstimg, w, h, col, x+hstep, y, x+hstep, y+step); } if (b==6) { drawline(dstimg, w, h, col, x+hstep, y, x, y+hstep); drawline(dstimg, w, h, col, x+hstep, y+step, x+step, y+hstep); } if (b==7 || b==8) { drawline(dstimg, w, h, col, x+hstep, y+step, x+step, y+hstep); } if (b==9) { drawline(dstimg, w, h, col, x+hstep, y, x+step, y+hstep); drawline(dstimg, w, h, col, x, y+hstep, x+hstep, y+step); } } } } f=fopen(argv[3],"wb"); assert(f); fprintf(f,"P6 %d %d %d\n", w,h,maxval); retval=fwrite(dstimg, 3*w*h, 1, f); assert(retval==1); fclose(f); fprintf(stderr, "image with %d isolines saved as %s\n", isocnt, argv[3]); }