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