home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / Graphics / ToyViewer-2.6a / src / ImageOpr.bproj / ImageEdge.m < prev    next >
Encoding:
Text File  |  1997-01-22  |  5.2 KB  |  230 lines

  1. /*
  2.     Edge Enhancement    coded by T.Ogihara
  3. */
  4.  
  5. #import "../ImageOpr.h"
  6. #import <appkit/Application.h>
  7. #import <appkit/publicWraps.h>
  8. #import <appkit/NXBitmapImageRep.h>
  9. #import <appkit/Control.h>
  10. #import <appkit/Panel.h>
  11. #import <stdio.h>
  12. #import <stdlib.h>
  13. #import <string.h>
  14. #import <streams/streams.h>
  15. #import "../TVController.h"
  16. #import "../ToyWin.h"
  17. #import "../ToyView.h"
  18. #import "../common.h"
  19. #import "../getpixel.h"
  20. #import "Posterizer.h"
  21. #import "imageOperation.h"
  22.  
  23.  
  24. @implementation ImageOpr (Edge)
  25.  
  26. static const char enhanceTab[5][5] = {
  27.     {0, 1, 1, 1, 0},
  28.     {1, 2, 3, 2, 1},
  29.     {1, 3, 0, 3, 1},
  30.     {1, 2, 3, 2, 1},
  31.     {0, 1, 1, 1, 0}
  32. };
  33. static const char embossTab[5][5] = {
  34.     {0,  0,  0,  0,  0},
  35.     {0, -2, -1,  0,  0},
  36.     {0, -1,  0,  1,  0},
  37.     {0,  0,  1,  2,  0},
  38.     {0,  0,  0,  0,  0}
  39. };
  40.  
  41.  
  42. static int edge(int op, commonInfo *cinf,
  43.     float factor, float bright, unsigned char **planes)
  44. {
  45.     int i, j, x, y, ptr;
  46.     int cnum, pnum;
  47.     int elm[MAXPLANE];
  48.     int alp, err;
  49.     const char (*weight)[5];
  50.  
  51.     cnum = pnum = cinf->numcolors;
  52.     if (cinf->alpha) alp = pnum++;
  53.     else alp = 0;
  54.     weight = (op == Enhance) ? enhanceTab: embossTab;
  55.  
  56.     err = allocImage(planes, cinf->width, cinf->height + 3, 8, pnum);
  57.     if (err) return err;
  58.  
  59.     for (y = 0; y < cinf->height; y++) {
  60.         ptr = cinf->width * (y + 3);
  61.         for (x = 0; x < cinf->width; x++) {
  62.             getPixel(&elm[0], &elm[1], &elm[2], &elm[3]);
  63.             for (i = 0; i < cnum; i++)
  64.                 planes[i][ptr] = elm[i];
  65.             if (alp) planes[alp][ptr] = elm[3];
  66.             ptr++;
  67.         }
  68.     }
  69.  
  70.     for (y = 0; y < cinf->height; y++) {
  71.         int curp, pw, n, v, w, totalw, totalv;
  72.         int xlow, xhigh, ylow, yhigh;
  73.  
  74.         ylow = (y > 2) ? -2 : -y;
  75.         if ((yhigh = cinf->height - 1 - y) > 2) yhigh = 2;
  76.         ptr = cinf->width * (y + 3);
  77.         curp = cinf->width * y;
  78.         for (x = 0; x < cinf->width; x++, ptr++, curp++) {
  79.             if (alp) {
  80.                 planes[alp][curp] = w = planes[alp][ptr];
  81.                 if (w == AlphaTransp) {
  82.                     for (n = 0; n < cnum; n++)
  83.                         planes[n][curp] = 255;
  84.                     continue;
  85.                 }
  86.             }
  87.             xlow = (x > 2) ? -2 : -x;
  88.             if ((xhigh = cinf->width - 1 - x) > 2) xhigh = 2;
  89.             for (n = 0; n < cnum; n++) {
  90.                 totalv = 0;
  91.                 totalw = 0;
  92.                 for (i = ylow; i < yhigh; i++) {
  93.                     pw = cinf->width * (y + 3 + i);
  94.                     for (j = xlow; j < xhigh; j++) {
  95.                     totalw += w = weight[i+2][j+2];
  96.                     if (w)
  97.                         totalv += planes[n][pw+x+j] * w;
  98.                     }
  99.                 }
  100.                 if (op == Enhance) {
  101.                     w = planes[n][ptr];
  102.                     v = totalv / totalw - w;
  103.                     w -= (int)(factor * v + 0.5);
  104.                 }else {
  105.                     w = (int)(factor * totalv);
  106.                     v = (planes[n][ptr] - 128) * bright;
  107.                     w += v + 128;
  108.                 }
  109.                 planes[n][curp] = (w < 0) ? 0
  110.                         : ((w > 255) ? 255 : w);
  111.             }
  112.         }
  113.     }
  114.  
  115.     return 0;
  116. }
  117.  
  118.  
  119. /* Local Method */
  120. - (int)doEnhance:(int)op filename:(const char *)fn map:(unsigned char **)map
  121.     parent:(ToyWin *)parent
  122.     info:(commonInfo *)cinf with:(float)degree : (float)bright
  123. {
  124.     ToyWin    *tw;
  125.     int    err = 0;
  126.     id    text;
  127.     commonInfo *newinf = NULL;
  128.     unsigned char *working[MAXPLANE];
  129.  
  130.     working[0] = NULL;
  131.     tw = NULL;
  132.     if ((newinf = (commonInfo *)malloc(sizeof(commonInfo))) == NULL)
  133.         goto ErrEXIT;
  134.     *newinf = *cinf;
  135.     newinf->bits = 8;
  136.     newinf->isplanar = YES;
  137.     newinf->xbytes = newinf->width;
  138.     newinf->palsteps = 0;
  139.     newinf->palette = NULL;
  140.     text = [theController messageDisplay:
  141.         (op == Enhance) ? "Enhancing..." :
  142.         ((op == Emboss) ? "Embossing..." : "Posterizing...")];
  143.     tw = [[ToyWin alloc] init:parent by:op];
  144.     [tw initLocateWindow:fn width:newinf->width height:newinf->height];
  145.     if (op == Posterize) {
  146.         id pos = [Posterizer alloc];
  147.         if (pos != nil && [pos initWith:cinf newmap:working]) {
  148.             [pos setMessageText: text];
  149.             [pos posterize:map with:degree : bright];
  150.         }else
  151.             err = Err_MEMORY;
  152.         if (pos) [pos free];
  153.     }else {
  154.         resetPixel(map, 0);
  155.         err = edge(op, cinf, degree, bright, working);
  156.     }
  157.     [theController messageDisplay:NULL];
  158.     if (err) goto ErrEXIT;
  159.     [tw makeComment: newinf from: cinf];
  160.     if ([tw drawView:working info: newinf] == nil)
  161.         goto ErrEXIT;
  162.     [theController newWindow: tw];
  163.  
  164.     return 0;
  165.  
  166. ErrEXIT:
  167.     if (working[0]) free((void *)working[0]);
  168.     if (newinf) free((void *)newinf);
  169.     if (tw) [tw free];
  170.     return Err_MEMORY;
  171. }
  172.  
  173. /* Local Method */
  174. - enhanceOrEmboss:(int)op and:(float)degree :(float)bright
  175. {
  176.     ToyWin    *tw;
  177.     ToyView    *tv = NULL;
  178.     NXImageRep    *rep;
  179.     commonInfo    *cinf;
  180.     unsigned char    *map[MAXPLANE];
  181.     char    fn[MAXFILENAMELEN];
  182.     const char *fnam, *opstr;
  183.     int    err;
  184.  
  185.     if (degree == 0.0 || (tw = [self keyParentWindow: op]) == nil) {
  186.         NXBeep();
  187.         return self;
  188.     }
  189.     tv = [tw toyView];
  190.     fnam = [tw filename];
  191.     cinf = [tv commonInfo];
  192.     if (![self checkCommonInfo:cinf filename:fnam]
  193.                 || cinf->width >= MAXWidth - 4)
  194.         return self;
  195.  
  196.     rep = [[tv image] bestRepresentation];
  197.     [(NXBitmapImageRep *)rep getDataPlanes: map];
  198.     if ((err = initGetPixel(cinf)) != 0) {
  199.         errAlert(fnam, err);
  200.         return self;
  201.     }
  202.     opstr = (op == Enhance) ? "Enhance":
  203.         ((op == Emboss) ? "Emboss" : "Posterize");
  204.     sprintf(fn, "%s(%s)", fnam, opstr);
  205.     if ((err = [self doEnhance:op filename:fn map:map
  206.             parent:tw info:cinf with:degree :bright]) != 0)
  207.         errAlert(fnam, err);
  208.     return self;
  209. }
  210.  
  211. - enhanceWith:(float)degree
  212. {
  213.     [self enhanceOrEmboss:Enhance and:degree : 0.0];
  214.     return self;
  215. }
  216.  
  217. - embossWith:(float)degree and:(float)bright
  218. {
  219.     [self enhanceOrEmboss:Emboss and:degree : bright];
  220.     return self;
  221. }
  222.  
  223. - posterizeWith:(float)diff and:(float)ctrl
  224. {
  225.     [self enhanceOrEmboss:Posterize and:diff : ctrl];
  226.     return self;
  227. }
  228.  
  229. @end
  230.