This is ImageMono.m in view mode; [Download] [Up]
#import "../ImageOpr.h"
#import <appkit/Application.h>
#import <appkit/publicWraps.h>
#import <appkit/NXEPSImageRep.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 "../ToyWinEPS.h"
#import "../ToyView.h"
#import "../PrefControl.h"
#import "../common.h"
#import "../strfunc.h"
#import "../getpixel.h"
#import "MDAmethod.h"
#import "Dither.h"
#import "imageOperation.h"
@implementation ImageOpr (Mono)
/* Local Method */
- (int)doMonochrome:(int)op parent:parent
filename:(const char *)fn info:(commonInfo *)cinf
scale:(const unsigned char *)scale method:(int)tag
{
ToyWin *tw;
commonInfo *newinf = NULL;
unsigned char *working[MAXPLANE];
int x, y, w;
int r, g, b, a;
int pn, binf = 1;
unsigned char *ptr, *pta;
working[0] = NULL;
tw = NULL;
if ((newinf = (commonInfo *)malloc(sizeof(commonInfo))) == NULL)
goto ErrEXIT;
*newinf = *cinf;
newinf->cspace = NX_OneIsWhiteColorSpace;
/* getPixel() fixes 0 as Black */
newinf->bits = 8;
newinf->numcolors = 1;
newinf->isplanar = YES;
newinf->xbytes = byte_length(newinf->bits, newinf->width);
newinf->palsteps = 0;
newinf->palette = NULL;
pn = newinf->alpha ? 2: 1;
w = newinf->width * newinf->height;
if ((working[0] = (unsigned char *)calloc(w * pn, 1)) == NULL)
goto ErrEXIT;
if (pn == 2) working[1] = working[0] + w;
tw = [[ToyWin alloc] init:parent by:op];
[tw initLocateWindow:fn width:newinf->width height:newinf->height];
if (op == Monochrome) {
for (y = 0; y < newinf->height; y++) {
ptr = &working[0][y * newinf->width];
pta = ptr + w;
for (x = 0; x < newinf->width; x++) {
getPixel(&r, &g, &b, &a);
r = Bright255(r, g, b);
ptr[x] = r = scale[r];
if (r && r != 255)
binf = 8;
if (pn == 2)
pta[x] = (a == AlphaTransp)
? AlphaTransp : AlphaOpaque;
}
}
}else {
unsigned char apool[MAXWidth];
id <Dithering> dither;
binf = (op == Gray2Bits) ? 2 : 1;
dither = tag ? [MDAmethod alloc] : [Dither alloc];
if (dither == nil
|| [dither init:(1 << binf) width:newinf->width] == nil)
goto ErrEXIT;
for (y = 0; y < newinf->height; y++) {
unsigned char *q;
q = [dither buffer];
ptr = &working[0][y * newinf->width];
for (x = 0; x < newinf->width; x++) {
getPixel(&r, &g, &b, &a);
r = Bright255(r, g, b);
*q++ = scale[r];
apool[x] = a;
}
q = [dither getNewLine];
for (x = 0; x < newinf->width; x++)
*ptr++ = *q++;
if (pn == 2) {
pta = &working[1][y * newinf->width];
for (x = 0; x < newinf->width; x++)
pta[x] = (apool[x] == AlphaTransp)
? AlphaTransp : AlphaOpaque;
}
}
[dither free];
}
if (binf < 8) {
unsigned char *planes[MAXPLANE];
if (pn == 2 && !hadAlpha()) {
pn = 1;
newinf->alpha = NO;
}
newinf->bits = binf;
newinf->xbytes = byte_length(newinf->bits, newinf->width);
if (allocImage(planes, newinf->width, newinf->height, binf, pn))
goto ErrEXIT;
packWorkingImage(newinf, pn, working, planes);
[tw makeComment: newinf from: cinf];
if ([tw drawView:planes info: newinf] == nil) {
free((void *)planes[0]);
goto ErrEXIT;
}
free((void *)working[0]);
}else {
if (pn == 2 && !hadAlpha()) {
pn = 1;
newinf->alpha = NO;
working[0] = (unsigned char *)realloc(working[0], w);
working[1] = NULL;
}
[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;
}
- monochrome:(int)op tone:(const unsigned char *)tone method:(int)tag
{
ToyWin *tw;
ToyView *tv = NULL;
NXImageRep *rep;
commonInfo *cinf;
unsigned char *map[MAXPLANE];
char fn[256];
const char *fnam, *ex = NULL;
int isby, err;
if ((tw = [theController keyWindow]) == nil) {
NXBeep();
return self;
}
isby = [tw madeby];
if (isby == Monochrome || isby == Gray2Bits || isby == BiLevel
|| isby == Brightness) {
ToyWin *win = [tw parent];
if (win && [theController isOpenedID: win])
tw = win;
}
tv = [tw toyView];
fnam = [tw filename];
cinf = [tv commonInfo];
if (cinf->numcolors == 1) {
if (cinf->bits == 1 || (op == Monochrome && !cinf->alpha)) {
warnAlert(fnam, Err_OPR_IMPL);
return self;
}
}
if (![self checkCommonInfo:cinf filename:fnam])
return self;
if (op == Brightness) {
ex = "Bright";
op = Monochrome;
}else if (op == Monochrome) ex = "Gray8";
else if (op == BiLevel) ex = "BiLevel";
else ex = "Gray2";
sprintf(fn, "%s(%s)", fnam, ex);
rep = [[tv image] bestRepresentation];
[(NXBitmapImageRep *)rep getDataPlanes: map];
if ((err = initGetPixel(cinf)) != 0) {
errAlert(fnam, err);
return self;
}
resetPixel(map, 0);
if ((err = [self doMonochrome:op parent:tw
filename:fn info:cinf scale:tone method:tag]) != 0)
errAlert(fnam, err);
return self;
}
/* Local Method */
- (int)doBrightness:(const char *)fn parent:(ToyWin *)parent
info:(commonInfo *)cinf scale:(const unsigned char *)scale
{
ToyWin *tw;
commonInfo *newinf = NULL;
unsigned char *working[MAXPLANE];
int x, y, pn;
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;
pn = newinf->alpha ? 4: 3;
if (allocImage(working, newinf->width, newinf->height, 8, pn))
goto ErrEXIT;
tw = [[ToyWin alloc] init:parent by:Brightness];
[tw initLocateWindow:fn width:newinf->width height:newinf->height];
for (y = 0; y < newinf->height; y++) {
int elm[MAXPLANE];
int i, v, ny, dd;
int ptr = y * newinf->width;
for (x = 0; x < newinf->width; x++) {
getPixel(&elm[0], &elm[1], &elm[2], &elm[3]);
if (elm[3] != AlphaTransp) {
ny = Bright255(elm[RED], elm[GREEN], elm[BLUE]);
if ((dd = scale[ny] - ny) != 0)
for (i = 0; i < 3; i++) {
v = elm[i] + dd;
elm[i] = (v > 255) ? 255 : ((v < 0) ? 0 : v);
}
}
for (i = 0; i < pn; i++)
working[i][ptr] = elm[i];
ptr++;
}
}
if (newinf->alpha && !hadAlpha()) {
pn = 3;
newinf->alpha = NO;
working[0] = (unsigned char *)
realloc(working[0], newinf->width * newinf->height * pn);
working[pn] = NULL;
}
[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;
}
- brightness:(const unsigned char *)tone
{
ToyWin *tw;
ToyView *tv = NULL;
NXImageRep *rep;
commonInfo *cinf;
unsigned char *map[MAXPLANE];
char fn[256];
const char *fnam;
int isby, err;
if ((tw = [theController keyWindow]) == nil) {
NXBeep();
return self;
}
isby = [tw madeby];
if (isby == Monochrome || isby == Gray2Bits || isby == BiLevel
|| isby == Brightness) {
ToyWin *win = [tw parent];
if (win && [theController isOpenedID: win])
tw = win;
}
tv = [tw toyView];
fnam = [tw filename];
cinf = [tv commonInfo];
if (cinf->numcolors == 1) /* Monochrome */
return [self monochrome:Brightness tone:tone method:1];
/* Don't Mind method: */
if (![self checkCommonInfo:cinf filename:fnam])
return self;
sprintf(fn, "%s(Bright)", fnam);
rep = [[tv image] bestRepresentation];
[(NXBitmapImageRep *)rep getDataPlanes: map];
if ((err = initGetPixel(cinf)) != 0) {
errAlert(fnam, err);
return self;
}
resetPixel(map, 0);
if ((err = [self doBrightness:fn parent:tw info:cinf scale:tone]) != 0)
errAlert(fnam, err);
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.