/*********************************************************/ /* program 25: pipelined morphological operations */ /*********************************************************/ #include #define XSIZE 640 #define YSIZE 480 long int interp(); main() { FILE *fp; char line[256]; unsigned char *ip; unsigned char *op; unsigned char *mp; unsigned char *i1,*i2,*i3; unsigned char *o1,*o2,*o3; unsigned char *m1,*m2,*m3; unsigned char lutm[512]; unsigned char lutu[512]; long int eof,m,u; long int x,y; long int diff; long int xx,x0,x1,x2,x3,x4,x5,x6,x7; long int l; /*********************************************************/ /* part 1: read in conditionals file and set up luts */ /*********************************************************/ /* open conditionals file */ fp = fopen("cshrink","r"); /******************************************************** file format (first token): # - comment line, ignored uncond - start of unconditional conditions mark - start of mark conditions 0 / 1 - 9-pixel condition (NE,N,NW,E,X,W,SE,S,SW) end - end of conditions ********************************************************/ /* initialize processing variables */ eof = 0; m = 0; u = 0; for (x = 0; x < 512; x++) lutm[x] = 0x00; for (x = 0; x < 512; x++) lutu[x] = 0x00; /* read and process all lines of file, build look-up tables ('lutu' and 'lutm') */ while (eof == 0) { if (fgets(line,255,fp) == NULL) { eof = 1; } else { if (line[0] != '#') { switch (m) { case 0: if (strncmp(line,"mark",4) == 0) { m = 1; } break; case 1: if (strncmp(line,"end",3) == 0) { m = 2; } else { x = interp(line); lutm[x] = 0xff; } break; case 2: switch (u) { case 0: if (strncmp(line,"uncond",6) == 0) { u = 1; } break; case 1: if (strncmp(line,"end",3) == 0) { u = 2; } else { x = interp(line); lutu[x] = 0xff; } break; default: printf("unknown: u=%d\n",u); break; } break; default: printf("unknown: m=%d\n",m); break; } } } } /*********************************************************/ /* part 2: process the image until final conclusions */ /*********************************************************/ ip = (unsigned char *) malloc (XSIZE*YSIZE); op = (unsigned char *) malloc (XSIZE*YSIZE); mp = (unsigned char *) malloc (XSIZE*YSIZE); /* read the input image (note: read into OUTPUT buffer) */ read_image("input",op); /* repetitively process the image until not changes are made */ diff = 1; while (diff > 0) { /* move last pass result (output) into input buffer */ for (x = 0; x < (XSIZE*YSIZE); x++) { *(ip+x) = *(op+x); *(mp+x) = 0x00; } /**** pipeline stage 1: ****/ /**** update undisputed pixels and mark potential pixels ****/ /* initialize pointers into buffers */ i2 = ip; i3 = ip + XSIZE; o2 = op; o3 = op + XSIZE; m2 = mp; m3 = mp + XSIZE; /* process all lines of image */ for (y = 1; y < (YSIZE-1); y++) { i1 = i2; i2 = i3; i3 = i3 + XSIZE; o1 = o2; o2 = o3; o3 = o3 + XSIZE; m1 = m2; m2 = m3; m3 = m3 + XSIZE; for (x = 1; x < (XSIZE-1); x++) { /* generate index into lut from binary pixels */ l = ((*(i2+x+0) & 0x01) << 8) + ((*(i2+x+1) & 0x01) << 7) + ((*(i1+x+1) & 0x01) << 6) + ((*(i1+x+0) & 0x01) << 5) + ((*(i1+x-1) & 0x01) << 4) + ((*(i2+x-1) & 0x01) << 3) + ((*(i3+x-1) & 0x01) << 2) + ((*(i3+x+0) & 0x01) << 1) + (*(i3+x+1) & 0x01); /* mark this pixel as a potential for change */ *(m2+x) = lutm[l]; /* if not a marked pixel, copy as-is to output buffer */ if (*(m2+x) == 0x00) *(o2+x) = *(i2+x); } } /**** pipeline stage 2: ****/ /**** revisit marked pixels and update accordingly ****/ /* re-initialize pointers into buffers */ i2 = ip; i3 = ip + XSIZE; o2 = op; o3 = op + XSIZE; m2 = mp; m3 = mp + XSIZE; /* process all lines of image */ for (y = 1; y < (YSIZE-1); y++) { i1 = i2; i2 = i3; i3 = i3 + XSIZE; o1 = o2; o2 = o3; o3 = o3 + XSIZE; m1 = m2; m2 = m3; m3 = m3 + XSIZE; for (x = 1; x < (XSIZE-1); x++) { /* check to see if this pixel is marked */ if (*(m2+x) == 0xff) { /* generate index into lut from binary pixels */ l = ((*(m2+x) & 0x01) << 8) + ((*(m2+x+1) & 0x01) << 7) + ((*(m1+x+1) & 0x01) << 6) + ((*(m1+x) & 0x01) << 5) + ((*(m1+x-1) & 0x01) << 4) + ((*(m2+x-1) & 0x01) << 3) + ((*(m3+x-1) & 0x01) << 2) + ((*(m3+x) & 0x01) << 1) + (*(m3+x+1) & 0x01); /* update output image for marked pixels */ *(o2+x) = lutu[l]; } } } /* determine if any pixels where changed during this pass */ diff = 0; for (x = 0; x < (XSIZE*YSIZE); x++) if (*(ip+x) != *(op+x)) diff++; printf("different pixel count: %d\n",diff); } /* write the output image */ write_image("output",op); /* free memory buffers */ free(ip); free(op); free(mp); } /****** interpret 9-pixel group ******/ long int interp(s) char *s; { long int z,z0,z1,z2,z3,z4,z5,z6,z7; long int i; sscanf(s,"%d %d %d %d %d %d %d %d %d", &z3,&z2,&z1,&z4,&z,&z0,&z5,&z6,&z7); i = ((z & 0x01) << 8) + ((z0 & 0x01) << 7) + ((z1 & 0x01) << 6) + ((z2 & 0x01) << 5) + ((z3 & 0x01) << 4) + ((z4 & 0x01) << 3) + ((z5 & 0x01) << 2) + ((z6 & 0x01) << 1) + (z7 & 0x01); return i; }