This is ImageOpr.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 <appkit/TextField.h> #import <stdio.h> #import <stdlib.h> #import <string.h> #import <streams/streams.h> #import <sys/types.h> #import <libc.h> #import "../TVController.h" #import "../ToyWin.h" #import "../ToyWinEPS.h" #import "../ToyView.h" #import "../common.h" #import "../getpixel.h" #import "imageOperation.h" @implementation ImageOpr - keyParentWindow:(int)op { ToyWin *tw, *win; if ((tw = [theController keyWindow]) == nil) return nil; if (op != NoOperation && [tw madeby] == op) { win = [tw parent]; if (win && [theController isOpenedID: win]) return win; } return tw; } - (BOOL)checkCommonInfo:(const commonInfo *)cinf filename:(const char *)fn { if (cinf->type == Type_eps) { warnAlert(fn, Err_EPS_IMPL); return NO; } if (cinf->cspace == NX_CMYKColorSpace) { warnAlert(fn, Err_IMPLEMENT); return NO; } if (cinf->width >= MAXWidth || cinf->height >= MAXWidth) { errAlert(fn, Err_MEMORY); return NO; } return YES; } static void sub_clip(NXRect *select, commonInfo *cinf, commonInfo *newinf, int idx[], unsigned char **working) { int x, y; int i, pidx, ptr; int pix[MAXPLANE]; int skipx = select->origin.x; int skipt = cinf->width - (skipx + select->size.width); int skipy = cinf->height - (select->origin.y + select->size.height); for (y = 0; y < skipy; y++) { for (x = 0; x < cinf->width; x++) getPixelA(pix); } for (y = 0; y < newinf->height; y++) { ptr = y * newinf->width; for (x = 0; x < skipx; x++) getPixelA(pix); for (x = 0; x < newinf->width; x++) { getPixelA(pix); for (i = 0; i <= ALPHA; i++) { if ((pidx = idx[i]) < 0) continue; working[pidx][ptr + x] = pix[i]; } } for (x = 0; x < skipt; x++) getPixelA(pix); } } /******* Random Functions ********/ #define ValBAND 32 #define BANDMask 0x1f #define ValBIAS 16 static int randomFreq = 0, randomMag = 0; - setRandom:(float)freq :(float)mag { if (!randomMag) srandom(getpid()); randomFreq = freq * freq * 256.0; randomMag = (int)(mag * mag * (ValBAND - ValBIAS + 256.0)) + ValBIAS; return self; } static int random_value(int pix) { long r, v; r = random(); if ((r & 0xff) >= randomFreq) return pix; r = random(); v = randomMag - ((r >> 1) & BANDMask); if (r & 1) v += pix; else v = pix - v; return (v > 255) ? 255 : ((v < 0) ? 0 : v); } static void sub_negative(int op, NXRect *select, commonInfo *newinf, int idx[], unsigned char **working) { int x, y; int i, pidx, ptr, alp; int pix[MAXPLANE]; int selectflag = NO, yout, xout; int skipx = 0, skipy = 0, yorig = 0; if (select && select->size.width > 0) { skipx = select->origin.x + select->size.width - 1; skipy = newinf->height - select->origin.y - 1; yorig = skipy - select->size.height + 1; selectflag = YES; } if ((alp = idx[ALPHA]) < 0) alp = 0; /* index of Alpha > 0 */ for (y = 0; y < newinf->height; y++) { yout = (selectflag && (y < yorig || y > skipy)); ptr = y * newinf->width; for (x = 0; x < newinf->width; x++) { xout = (yout || (selectflag && (x < select->origin.x || x > skipx))); getPixelA(pix); if (xout) { for (i = 0; i < ALPHA; i++) { if ((pidx = idx[i]) < 0) continue; working[pidx][ptr + x] = pix[i]; } }else if (op == Negative) { for (i = 0; i < ALPHA; i++) { if ((pidx = idx[i]) < 0) continue; working[pidx][ptr + x] = 0xff - pix[i]; } }else { for (i = 0; i < ALPHA; i++) { if ((pidx = idx[i]) < 0) continue; working[pidx][ptr + x] = random_value(pix[i]); } } if (alp) /* Alpha */ working[alp][ptr + x] = pix[i]; } } if (newinf->palette) { unsigned char *p; paltype *pal = newinf->palette; for (x = 0; x < newinf->palsteps; x++) { p = pal[x]; for (i = 0; i < 3; i++) p[i] = 0xff - p[i]; } } } /* Local Method */ - doBitmap:(int)op parent:parent filename:(const char *)fn info:(commonInfo *)cinf to:(int)angle rect:(NXRect *)select { ToyWin *tw; commonInfo *newinf = NULL; unsigned char *working[MAXPLANE], *planes[MAXPLANE]; int i, pl; int idx[MAXPLANE]; BOOL rotalpha = NO, hadalpha = NO; working[0] = planes[0] = NULL; tw = NULL; if ((newinf = (commonInfo *)malloc(sizeof(commonInfo))) == NULL) goto ErrEXIT; *newinf = *cinf; if (cinf->cspace == NX_OneIsBlackColorSpace) newinf->cspace = NX_OneIsWhiteColorSpace; /* getPixel() fixes 0 as Black */ newinf->isplanar = YES; if (op == Rotation) { rotate_size(angle, cinf, newinf); if (newinf->width >= MAXWidth || newinf->height >= MAXWidth) goto ErrEXIT; }else if (op == Clip) { newinf->width = select->size.width; newinf->height = select->size.height; } newinf->xbytes = byte_length(newinf->bits, newinf->width); /** if rotalpha==YES one color(transparent) is added **/ if (cinf->palette && (cinf->alpha || !rotalpha || newinf->palsteps < FIXcount)) { newinf->palette = copyPalette(cinf->palette, newinf->palsteps); if (newinf->palette == NULL) goto ErrEXIT; }else { newinf->palette = NULL; newinf->palsteps = 0; } pl = newinf->numcolors; for (i = 0; i < pl; i++) idx[i] = i; for (i = pl; i < MAXPLANE; i++) idx[i] = -1; if (op == Rotation && (angle % 90 != 0)) newinf->alpha = rotalpha = YES; if (newinf->alpha) idx[ALPHA] = pl++; if (allocImage(working, newinf->width, newinf->height, 8, pl)) goto ErrEXIT; tw = [[ToyWin alloc] init:parent by:op]; [tw initLocateWindow:fn width:newinf->width height:newinf->height]; if (op == Clip) { sub_clip(select, cinf, newinf, idx, working); if (newinf->alpha) { int aw = newinf->width * newinf->height; unsigned char *ap = working[pl-1]; for (i = 0; i < aw; i++, ap++) if (isAlphaTransp(*ap)) { hadalpha = YES; break; } } }else if (op == Negative || op == RandomPttn) { sub_negative(op, select, newinf, idx, working); if (newinf->alpha) hadalpha = hadAlpha(); }else /* Rotation | Horizontal | Vertical */ { if (sub_rotate(op, angle, cinf, newinf, idx, working)) goto ErrEXIT; if (rotalpha) hadalpha = YES; else if (newinf->alpha) hadalpha = hadAlpha(); } if (newinf->alpha && !hadalpha) { newinf->alpha = NO; working[--pl] = NULL; } if (newinf->alpha && newinf->palette && newinf->palsteps >= 256) { free((void *)newinf->palette); /* 256 colors are too much */ newinf->palette = NULL; newinf->palsteps = 0; } [tw makeComment: newinf from: cinf]; if (newinf->bits < 8) { if (allocImage(planes, newinf->width, newinf->height, newinf->bits, pl)) goto ErrEXIT; packWorkingImage(newinf, pl, working, planes); if ([tw drawView:planes info: newinf] == nil) goto ErrEXIT; free((void *)working[0]); }else { if ([tw drawView:working info: newinf] == nil) goto ErrEXIT; } [theController newWindow: tw]; return self; ErrEXIT: if (working[0]) free((void *)working[0]); if (planes[0]) free((void *)planes[0]); if (newinf) { if (newinf->palette) free((void *)newinf->palette); free((void *)newinf); } if (tw) [[tw window] performClose: self]; /* This call frees tw */ return nil; } - doRotateFlipClip: (int)op to:(int)angle { ToyWin *tw; ToyView *tv = NULL; NXImageRep *rep; commonInfo *cinf; NXRect *select = NULL; unsigned char *map[MAXPLANE]; const char *ex = NULL, *fnam; char fn[256]; int err; if ((tw = [theController keyWindow]) != nil) { tv = [tw toyView]; if (op == Clip) { select = [tv selectedScaledRect]; if (select->size.width < 1.0 || select->size.height < 1.0) tw = nil; }else if (op == Negative || op == RandomPttn) select = [tv selectedScaledRect]; } if (tw == nil) { NXBeep(); return self; } cinf = [tv commonInfo]; if (cinf->width >= MAXWidth || cinf->height >= MAXWidth) { errAlert([tw filename], Err_MEMORY); return self; } switch (op) { case Rotation: ex = "Rotate"; break; case Clip: ex = "Clip"; break; case Negative: ex = "Negative"; break; case RandomPttn: ex = "Random"; break; case Horizontal: case Vertical: default: ex = "Flip"; break; } fnam = [tw filename]; sprintf(fn, "%s(%s)", fnam, ex); if (cinf->type == Type_eps) { NXStream *stream; ToyWinEPS *newtw; commonInfo info; if (op == Negative || op == RandomPttn) { warnAlert(fnam, Err_EPS_IMPL); return self; } if (op == Clip) stream = [(ToyWinEPS *)tw clipEPS:select error:&err]; else { /* Rotate | Horizontal | Vertical */ rotate_size(angle, cinf, &info); stream = [(ToyWinEPS *)tw rotateEPS:op to:angle width:info.width height:info.height name:fn error:&err]; } if (stream == NULL) { errAlert(fnam, err); return self; } newtw = [[ToyWinEPS alloc] init:tw by:op]; err = [newtw drawFromFile:(const char *)fn or:stream]; NXCloseMemory(stream, NX_FREEBUFFER); if (err) { errAlert(fnam, err); [newtw free]; }else [theController newWindow: newtw]; return self; } if (cinf->cspace == NX_CMYKColorSpace) { warnAlert(fnam, Err_IMPLEMENT); return self; } rep = [[tv image] bestRepresentation]; [(NXBitmapImageRep *)rep getDataPlanes: map]; if ((err = initGetPixel(cinf)) != 0) { errAlert(fnam, err); return self; } resetPixel(map, 0); if ([self doBitmap:op parent:tw filename:fn info:cinf to:angle rect:select] == nil) errAlert(fn, Err_MEMORY); return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.