home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / Graphics / ToyViewer-2.6a / src / ImageOpr.bproj / ImageMono.m < prev    next >
Encoding:
Text File  |  1996-10-04  |  7.7 KB  |  319 lines

  1. #import "../ImageOpr.h"
  2. #import <appkit/Application.h>
  3. #import <appkit/publicWraps.h>
  4. #import <appkit/NXEPSImageRep.h>
  5. #import <appkit/NXBitmapImageRep.h>
  6. #import <appkit/Control.h>
  7. #import <appkit/Panel.h>
  8. #import <stdio.h>
  9. #import <stdlib.h>
  10. #import <string.h>
  11. #import <streams/streams.h>
  12. #import "../TVController.h"
  13. #import "../ToyWin.h"
  14. #import "../ToyWinEPS.h"
  15. #import "../ToyView.h"
  16. #import "../PrefControl.h"
  17. #import "../common.h"
  18. #import "../strfunc.h"
  19. #import "../getpixel.h"
  20. #import "MDAmethod.h"
  21. #import "Dither.h"
  22. #import "imageOperation.h"
  23.  
  24.  
  25. @implementation ImageOpr (Mono)
  26.  
  27. /* Local Method */
  28. - (int)doMonochrome:(int)op parent:parent
  29.     filename:(const char *)fn info:(commonInfo *)cinf
  30.     scale:(const unsigned char *)scale method:(int)tag
  31. {
  32.     ToyWin    *tw;
  33.     commonInfo *newinf = NULL;
  34.     unsigned char *working[MAXPLANE];
  35.     int    x, y, w;
  36.     int    r, g, b, a;
  37.     int    pn, binf = 1;
  38.     unsigned char *ptr, *pta;
  39.  
  40.     working[0] = NULL;
  41.     tw = NULL;
  42.     if ((newinf = (commonInfo *)malloc(sizeof(commonInfo))) == NULL)
  43.         goto ErrEXIT;
  44.     *newinf = *cinf;
  45.     newinf->cspace = NX_OneIsWhiteColorSpace;
  46.         /* getPixel() fixes 0 as Black */
  47.     newinf->bits = 8;
  48.     newinf->numcolors = 1;
  49.     newinf->isplanar = YES;
  50.     newinf->xbytes = byte_length(newinf->bits, newinf->width);
  51.     newinf->palsteps = 0;
  52.     newinf->palette = NULL;
  53.     pn = newinf->alpha ? 2: 1;
  54.  
  55.     w = newinf->width * newinf->height;
  56.     if ((working[0] = (unsigned char *)calloc(w * pn, 1)) == NULL)
  57.         goto ErrEXIT;
  58.     if (pn == 2) working[1] = working[0] + w;
  59.  
  60.     tw = [[ToyWin alloc] init:parent by:op];
  61.     [tw initLocateWindow:fn width:newinf->width height:newinf->height];
  62.  
  63.     if (op == Monochrome) {
  64.         for (y = 0; y < newinf->height; y++) {
  65.             ptr = &working[0][y * newinf->width];
  66.             pta = ptr + w;
  67.             for (x = 0; x < newinf->width; x++) {
  68.                 getPixel(&r, &g, &b, &a);
  69.                 r = Bright255(r, g, b);
  70.                 ptr[x] = r = scale[r];
  71.                 if (r && r != 255)
  72.                     binf = 8;
  73.                 if (pn == 2)
  74.                     pta[x] = (a == AlphaTransp)
  75.                         ? AlphaTransp : AlphaOpaque;
  76.             }
  77.         }
  78.     }else {
  79.         unsigned char apool[MAXWidth];
  80.         id <Dithering> dither;
  81.  
  82.         binf = (op == Gray2Bits) ? 2 : 1;
  83.         dither = tag ? [MDAmethod alloc] : [Dither alloc];
  84.         if (dither == nil 
  85.         || [dither init:(1 << binf) width:newinf->width] == nil)
  86.             goto ErrEXIT;
  87.         for (y = 0; y < newinf->height; y++) {
  88.             unsigned char *q;
  89.             q = [dither buffer];
  90.             ptr = &working[0][y * newinf->width];
  91.             for (x = 0; x < newinf->width; x++) {
  92.                 getPixel(&r, &g, &b, &a);
  93.                 r = Bright255(r, g, b);
  94.                 *q++ = scale[r];
  95.                 apool[x] = a;
  96.             }
  97.             q = [dither getNewLine];
  98.             for (x = 0; x < newinf->width; x++)
  99.                 *ptr++ = *q++;
  100.             if (pn == 2) {
  101.                 pta = &working[1][y * newinf->width];
  102.                 for (x = 0; x < newinf->width; x++)
  103.                     pta[x] = (apool[x] == AlphaTransp)
  104.                         ? AlphaTransp : AlphaOpaque;
  105.             }
  106.         }
  107.         [dither free];
  108.     }
  109.  
  110.     if (binf < 8) {
  111.         unsigned char *planes[MAXPLANE];
  112.         if (pn == 2 && !hadAlpha()) {
  113.             pn = 1;
  114.             newinf->alpha = NO;
  115.         }
  116.         newinf->bits = binf;
  117.         newinf->xbytes = byte_length(newinf->bits, newinf->width);
  118.         if (allocImage(planes, newinf->width, newinf->height, binf, pn))
  119.             goto ErrEXIT;
  120.         packWorkingImage(newinf, pn, working, planes);
  121.         [tw makeComment: newinf from: cinf];
  122.         if ([tw drawView:planes info: newinf] == nil) {
  123.             free((void *)planes[0]);
  124.             goto ErrEXIT;
  125.         }
  126.         free((void *)working[0]);
  127.     }else {
  128.         if (pn == 2 && !hadAlpha()) {
  129.             pn = 1;
  130.             newinf->alpha = NO;
  131.             working[0] = (unsigned char *)realloc(working[0], w);
  132.             working[1] = NULL;
  133.         }
  134.         [tw makeComment:newinf from:cinf];
  135.         if ([tw drawView:working info: newinf] == nil)
  136.             goto ErrEXIT;
  137.     }
  138.     [theController newWindow: tw];
  139.     return 0;
  140.  
  141. ErrEXIT:
  142.     if (working[0]) free((void *)working[0]);
  143.     if (newinf) free((void *)newinf);
  144.     if (tw) [tw free];
  145.     return Err_MEMORY;
  146. }
  147.  
  148.  
  149. - monochrome:(int)op tone:(const unsigned char *)tone method:(int)tag
  150. {
  151.     ToyWin    *tw;
  152.     ToyView    *tv = NULL;
  153.     NXImageRep    *rep;
  154.     commonInfo    *cinf;
  155.     unsigned char    *map[MAXPLANE];
  156.     char    fn[256];
  157.     const char *fnam, *ex = NULL;
  158.     int    isby, err;
  159.  
  160.     if ((tw = [theController keyWindow]) == nil) {
  161.         NXBeep();
  162.         return self;
  163.     }
  164.     isby = [tw madeby];
  165.     if (isby == Monochrome || isby == Gray2Bits || isby == BiLevel
  166.         || isby == Brightness) {
  167.         ToyWin    *win = [tw parent];
  168.         if (win && [theController isOpenedID: win])
  169.             tw = win;
  170.     }
  171.  
  172.     tv = [tw toyView];
  173.     fnam = [tw filename];
  174.     cinf = [tv commonInfo];
  175.     if (cinf->numcolors == 1) {
  176.         if (cinf->bits == 1 || (op == Monochrome && !cinf->alpha)) {
  177.             warnAlert(fnam, Err_OPR_IMPL);
  178.             return self;
  179.         }
  180.     }
  181.     if (![self checkCommonInfo:cinf filename:fnam])
  182.         return self;
  183.     if (op == Brightness) {
  184.         ex = "Bright";
  185.         op = Monochrome;
  186.     }else if (op == Monochrome) ex = "Gray8";
  187.     else if (op == BiLevel) ex = "BiLevel";
  188.     else ex = "Gray2";
  189.     sprintf(fn, "%s(%s)", fnam, ex);
  190.  
  191.     rep = [[tv image] bestRepresentation];
  192.     [(NXBitmapImageRep *)rep getDataPlanes: map];
  193.     if ((err = initGetPixel(cinf)) != 0) {
  194.         errAlert(fnam, err);
  195.         return self;
  196.     }
  197.     resetPixel(map, 0);
  198.     if ((err = [self doMonochrome:op parent:tw
  199.         filename:fn info:cinf scale:tone method:tag]) != 0)
  200.         errAlert(fnam, err);
  201.     return self;
  202. }
  203.  
  204.  
  205. /* Local Method */
  206. - (int)doBrightness:(const char *)fn parent:(ToyWin *)parent
  207.     info:(commonInfo *)cinf scale:(const unsigned char *)scale
  208. {
  209.     ToyWin    *tw;
  210.     commonInfo *newinf = NULL;
  211.     unsigned char *working[MAXPLANE];
  212.     int    x, y, pn;
  213.  
  214.     working[0] = NULL;
  215.     tw = NULL;
  216.     if ((newinf = (commonInfo *)malloc(sizeof(commonInfo))) == NULL)
  217.         goto ErrEXIT;
  218.     *newinf = *cinf;
  219.     newinf->bits = 8;
  220.     newinf->isplanar = YES;
  221.     newinf->xbytes = newinf->width;
  222.     newinf->palsteps = 0;
  223.     newinf->palette = NULL;
  224.     pn = newinf->alpha ? 4: 3;
  225.  
  226.     if (allocImage(working, newinf->width, newinf->height, 8, pn))
  227.         goto ErrEXIT;
  228.  
  229.     tw = [[ToyWin alloc] init:parent by:Brightness];
  230.     [tw initLocateWindow:fn width:newinf->width height:newinf->height];
  231.  
  232.     for (y = 0; y < newinf->height; y++) {
  233.         int  elm[MAXPLANE];
  234.         int  i, v, ny, dd;
  235.         int  ptr = y * newinf->width;
  236.         for (x = 0; x < newinf->width; x++) {
  237.         getPixel(&elm[0], &elm[1], &elm[2], &elm[3]);
  238.         if (elm[3] != AlphaTransp) {
  239.             ny = Bright255(elm[RED], elm[GREEN], elm[BLUE]);
  240.             if ((dd = scale[ny] - ny) != 0)
  241.                 for (i = 0; i < 3; i++) {
  242.                 v = elm[i] + dd;
  243.                 elm[i] = (v > 255) ? 255 : ((v < 0) ? 0 : v);
  244.                 }
  245.         }
  246.         for (i = 0; i < pn; i++)
  247.             working[i][ptr] = elm[i];
  248.         ptr++;
  249.         }
  250.     }
  251.  
  252.     if (newinf->alpha && !hadAlpha()) {
  253.         pn = 3;
  254.         newinf->alpha = NO;
  255.         working[0] = (unsigned char *)
  256.             realloc(working[0], newinf->width * newinf->height * pn);
  257.         working[pn] = NULL;
  258.     }
  259.     [tw makeComment: newinf from: cinf];
  260.     if ([tw drawView:working info: newinf] == nil)
  261.         goto ErrEXIT;
  262.  
  263.     [theController newWindow: tw];
  264.     return 0;
  265.  
  266. ErrEXIT:
  267.     if (working[0]) free((void *)working[0]);
  268.     if (newinf) free((void *)newinf);
  269.     if (tw) [tw free];
  270.     return Err_MEMORY;
  271. }
  272.  
  273. - brightness:(const unsigned char *)tone
  274. {
  275.     ToyWin    *tw;
  276.     ToyView    *tv = NULL;
  277.     NXImageRep    *rep;
  278.     commonInfo    *cinf;
  279.     unsigned char    *map[MAXPLANE];
  280.     char    fn[256];
  281.     const char *fnam;
  282.     int    isby, err;
  283.  
  284.     if ((tw = [theController keyWindow]) == nil) {
  285.         NXBeep();
  286.         return self;
  287.     }
  288.     isby = [tw madeby];
  289.     if (isby == Monochrome || isby == Gray2Bits || isby == BiLevel
  290.         || isby == Brightness) {
  291.         ToyWin    *win = [tw parent];
  292.         if (win && [theController isOpenedID: win])
  293.             tw = win;
  294.     }
  295.     tv = [tw toyView];
  296.     fnam = [tw filename];
  297.     cinf = [tv commonInfo];
  298.     if (cinf->numcolors == 1)    /* Monochrome */
  299.         return [self monochrome:Brightness tone:tone method:1];
  300.             /* Don't Mind method: */
  301.  
  302.     if (![self checkCommonInfo:cinf filename:fnam])
  303.         return self;
  304.     sprintf(fn, "%s(Bright)", fnam);
  305.  
  306.     rep = [[tv image] bestRepresentation];
  307.     [(NXBitmapImageRep *)rep getDataPlanes: map];
  308.     if ((err = initGetPixel(cinf)) != 0) {
  309.         errAlert(fnam, err);
  310.         return self;
  311.     }
  312.     resetPixel(map, 0);
  313.     if ((err = [self doBrightness:fn parent:tw info:cinf scale:tone]) != 0)
  314.         errAlert(fnam, err);
  315.     return self;
  316. }
  317.  
  318. @end
  319.