home *** CD-ROM | disk | FTP | other *** search
- /*
- 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
-