This is ImageEdge.m in view mode; [Download] [Up]
/* Edge Enhancement coded by T.Ogihara */ #import "../ImageOpr.h" #import <appkit/Application.h> #import <appkit/publicWraps.h> #import <appkit/NXBitmapImageRep.h> #import <appkit/Control.h> #import <appkit/Panel.h> #import <stdio.h> #import <stdlib.h> #import <string.h> #import <streams/streams.h> #import "../TVController.h" #import "../ToyWin.h" #import "../ToyView.h" #import "../common.h" #import "../getpixel.h" #import "Posterizer.h" #import "imageOperation.h" @implementation ImageOpr (Edge) static const char enhanceTab[5][5] = { {0, 1, 1, 1, 0}, {1, 2, 3, 2, 1}, {1, 3, 0, 3, 1}, {1, 2, 3, 2, 1}, {0, 1, 1, 1, 0} }; static const char embossTab[5][5] = { {0, 0, 0, 0, 0}, {0, -2, -1, 0, 0}, {0, -1, 0, 1, 0}, {0, 0, 1, 2, 0}, {0, 0, 0, 0, 0} }; static int edge(int op, commonInfo *cinf, float factor, float bright, unsigned char **planes) { int i, j, x, y, ptr; int cnum, pnum; int elm[MAXPLANE]; int alp, err; const char (*weight)[5]; cnum = pnum = cinf->numcolors; if (cinf->alpha) alp = pnum++; else alp = 0; weight = (op == Enhance) ? enhanceTab: embossTab; err = allocImage(planes, cinf->width, cinf->height + 3, 8, pnum); if (err) return err; for (y = 0; y < cinf->height; y++) { ptr = cinf->width * (y + 3); for (x = 0; x < cinf->width; x++) { getPixel(&elm[0], &elm[1], &elm[2], &elm[3]); for (i = 0; i < cnum; i++) planes[i][ptr] = elm[i]; if (alp) planes[alp][ptr] = elm[3]; ptr++; } } for (y = 0; y < cinf->height; y++) { int curp, pw, n, v, w, totalw, totalv; int xlow, xhigh, ylow, yhigh; ylow = (y > 2) ? -2 : -y; if ((yhigh = cinf->height - 1 - y) > 2) yhigh = 2; ptr = cinf->width * (y + 3); curp = cinf->width * y; for (x = 0; x < cinf->width; x++, ptr++, curp++) { if (alp) { planes[alp][curp] = w = planes[alp][ptr]; if (w == AlphaTransp) { for (n = 0; n < cnum; n++) planes[n][curp] = 255; continue; } } xlow = (x > 2) ? -2 : -x; if ((xhigh = cinf->width - 1 - x) > 2) xhigh = 2; for (n = 0; n < cnum; n++) { totalv = 0; totalw = 0; for (i = ylow; i < yhigh; i++) { pw = cinf->width * (y + 3 + i); for (j = xlow; j < xhigh; j++) { totalw += w = weight[i+2][j+2]; if (w) totalv += planes[n][pw+x+j] * w; } } if (op == Enhance) { w = planes[n][ptr]; v = totalv / totalw - w; w -= (int)(factor * v + 0.5); }else { w = (int)(factor * totalv); v = (planes[n][ptr] - 128) * bright; w += v + 128; } planes[n][curp] = (w < 0) ? 0 : ((w > 255) ? 255 : w); } } } return 0; } /* Local Method */ - (int)doEnhance:(int)op filename:(const char *)fn map:(unsigned char **)map parent:(ToyWin *)parent info:(commonInfo *)cinf with:(float)degree : (float)bright { ToyWin *tw; int err = 0; id text; commonInfo *newinf = NULL; unsigned char *working[MAXPLANE]; working[0] = NULL; tw = NULL; if ((newinf = (commonInfo *)malloc(sizeof(commonInfo))) == NULL) goto ErrEXIT; *newinf = *cinf; newinf->bits = 8; newinf->isplanar = YES; newinf->xbytes = newinf->width; newinf->palsteps = 0; newinf->palette = NULL; text = [theController messageDisplay: (op == Enhance) ? "Enhancing..." : ((op == Emboss) ? "Embossing..." : "Posterizing...")]; tw = [[ToyWin alloc] init:parent by:op]; [tw initLocateWindow:fn width:newinf->width height:newinf->height]; if (op == Posterize) { id pos = [Posterizer alloc]; if (pos != nil && [pos initWith:cinf newmap:working]) { [pos setMessageText: text]; [pos posterize:map with:degree : bright]; }else err = Err_MEMORY; if (pos) [pos free]; }else { resetPixel(map, 0); err = edge(op, cinf, degree, bright, working); } [theController messageDisplay:NULL]; if (err) goto ErrEXIT; [tw makeComment: newinf from: cinf]; if ([tw drawView:working info: newinf] == nil) goto ErrEXIT; [theController newWindow: tw]; return 0; ErrEXIT: if (working[0]) free((void *)working[0]); if (newinf) free((void *)newinf); if (tw) [tw free]; return Err_MEMORY; } /* Local Method */ - enhanceOrEmboss:(int)op and:(float)degree :(float)bright { ToyWin *tw; ToyView *tv = NULL; NXImageRep *rep; commonInfo *cinf; unsigned char *map[MAXPLANE]; char fn[MAXFILENAMELEN]; const char *fnam, *opstr; int err; if (degree == 0.0 || (tw = [self keyParentWindow: op]) == nil) { NXBeep(); return self; } tv = [tw toyView]; fnam = [tw filename]; cinf = [tv commonInfo]; if (![self checkCommonInfo:cinf filename:fnam] || cinf->width >= MAXWidth - 4) return self; rep = [[tv image] bestRepresentation]; [(NXBitmapImageRep *)rep getDataPlanes: map]; if ((err = initGetPixel(cinf)) != 0) { errAlert(fnam, err); return self; } opstr = (op == Enhance) ? "Enhance": ((op == Emboss) ? "Emboss" : "Posterize"); sprintf(fn, "%s(%s)", fnam, opstr); if ((err = [self doEnhance:op filename:fn map:map parent:tw info:cinf with:degree :bright]) != 0) errAlert(fnam, err); return self; } - enhanceWith:(float)degree { [self enhanceOrEmboss:Enhance and:degree : 0.0]; return self; } - embossWith:(float)degree and:(float)bright { [self enhanceOrEmboss:Emboss and:degree : bright]; return self; } - posterizeWith:(float)diff and:(float)ctrl { [self enhanceOrEmboss:Posterize and:diff : ctrl]; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.