home *** CD-ROM | disk | FTP | other *** search
- #import "TVController.h"
- #import <appkit/Application.h>
- #import <appkit/publicWraps.h>
- #import <appkit/NXEPSImageRep.h>
- #import <appkit/NXBitmapImageRep.h>
- #import <appkit/Control.h>
- #import <stdio.h>
- #import <stdlib.h>
- #import <string.h>
- #import <streams/streams.h>
- #import "ToyWin.h"
- #import "ToyWinEPS.h"
- #import "ToyView.h"
- #import "save.h"
- #import "common.h"
-
- #define Width45(x,y) ((((x)+1) >> 1) + (((y)+1) >> 1))
- #define NewLoc 13
-
- @implementation TVController (Rotate)
-
- static void packWorkingImage(const commonInfo *newinf, int pl,
- unsigned char **working, unsigned char **planes)
- {
- int pn, y;
- unsigned char *pp, *ww;
-
- for (pn = 0; pn < pl; pn++) {
- for (y = 0; y < newinf->height; y++) {
- ww = working[pn] + y * newinf->width;
- pp = planes[pn] + y * newinf->xbytes;
- packImage(pp, ww, newinf->width, newinf->bits);
- }
- }
- }
-
- /* Local Method */
- - doBitmap: (const char *)fn info:(commonInfo *)cinf
- to:(int)angle rect:(NXRect *)select
- {
- ToyWin *tw;
- commonInfo *newinf = NULL;
- unsigned char *working[5], *planes[5];
- int i, pidx, ptr, x, y, w, pl;
- int pix[5], idx[5];
-
- 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 (angle == 90 || angle == 270) {
- newinf->width = cinf->height;
- newinf->height = cinf->width;
- }else if (angle == 45) {
- newinf->width = newinf->height
- = Width45(cinf->width, cinf->height);
- }else if (angle == Clip) {
- newinf->width = select->size.width;
- newinf->height = select->size.height;
- }
- newinf->xbytes = byte_length(newinf->bits, newinf->width);
- newinf->palette = NULL;
- if (cinf->palette) {
- w = sizeof(paltype) * newinf->palsteps;
- if ((newinf->palette = (paltype *)malloc(w)) == NULL)
- goto ErrEXIT;
- memcpy((void *)newinf->palette, (void *)cinf->palette, w);
- }
-
- pl = newinf->numcolors;
- for (i = 0; i < pl; i++) idx[i] = i;
- for (i = pl; i < 5; i++) idx[i] = -1;
- if (newinf->alpha) idx[ALPHA] = pl++;
- w = newinf->width * newinf->height;
- if ((working[0] = (unsigned char *)calloc(w * pl, 1)) == NULL)
- goto ErrEXIT;
- for (i = 1; i < pl; i++)
- working[i] = working[i - 1] + w;
- if (newinf->bits < 8) {
- w = newinf->xbytes * newinf->height;
- if ((planes[0] = (unsigned char *)malloc(w * pl)) == NULL)
- goto ErrEXIT;
- for (i = 1; i < pl; i++)
- planes[i] = planes[i - 1] + w;
- }
-
- tw = [[ToyWin alloc] init: self];
- [tw initLocateWindow:fn
- Width:newinf->width Height:newinf->height Num:NewLoc];
-
- if (angle == 45) {
- int yorg = (cinf->width + 1) >> 1;
- int xt, yt;
- for (y = 0; y < cinf->height; y++) {
- for (x = 0; x < cinf->width; x++) {
- getPixelA(pix);
- if (((xt = x + y) & 1) == 0) {
- xt >>= 1;
- yt = yorg + ((y - x) >> 1);
- ptr = yt * newinf->width;
- for (i = 0; i <= ALPHA; i++) {
- if ((pidx = idx[i]) < 0) continue;
- working[pidx][ptr + xt] = pix[i];
- }
- }
- }
- }
- }else if (angle == 90) {
- for (x = 0; x < newinf->width; x++) {
- for (y = newinf->height - 1; y >= 0; y--) {
- ptr = y * newinf->width;
- getPixelA(pix);
- for (i = 0; i <= ALPHA; i++) {
- if ((pidx = idx[i]) < 0) continue;
- working[pidx][ptr + x] = pix[i];
- }
- }
- }
- }else if (angle == 270) {
- for (x = newinf->width - 1; x >= 0; x--) {
- for (y = 0; y < newinf->height; y++) {
- ptr = y * newinf->width;
- getPixelA(pix);
- for (i = 0; i <= ALPHA; i++) {
- if ((pidx = idx[i]) < 0) continue;
- working[pidx][ptr + x] = pix[i];
- }
- }
- }
- }else if (angle == 180) {
- for (y = newinf->height - 1; y >= 0; y--) {
- ptr = y * newinf->width;
- for (x = newinf->width - 1; x >= 0; x--) {
- getPixelA(pix);
- for (i = 0; i <= ALPHA; i++) {
- if ((pidx = idx[i]) < 0) continue;
- working[pidx][ptr + x] = pix[i];
- }
- }
- }
- }else if (angle == Horizontal) {
- for (y = 0; y < newinf->height; y++) {
- ptr = y * newinf->width;
- for (x = newinf->width - 1; x >= 0; x--) {
- getPixelA(pix);
- for (i = 0; i <= ALPHA; i++) {
- if ((pidx = idx[i]) < 0) continue;
- working[pidx][ptr + x] = pix[i];
- }
- }
- }
- }else if (angle == Vertical) {
- for (y = newinf->height - 1; y >= 0; y--) {
- ptr = y * newinf->width;
- 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];
- }
- }
- }
- }else if (angle == Clip) {
- 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);
- }
- }else /* Negative */ {
- for (y = 0; y < newinf->height; y++) {
- ptr = y * newinf->width;
- 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] = 0xff - 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];
- }
- }
- }
-
- sprintf(newinf->memo, "%d x %d %dbit%s",
- newinf->width, newinf->height, newinf->bits,
- ((newinf->bits > 1) ? "s" : ""));
- if (newinf->bits < 8) {
- 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;
- }
- [self 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 free];
- return nil;
- }
-
-
- - doRotateFlipClip: (int)angle
- {
- ToyWin *tw;
- ToyView *tv = NULL;
- NXImageRep *rep;
- commonInfo *cinf;
- NXRect *select = NULL, rct;
- unsigned char *map[5];
- char *ex = NULL, fn[256];
- float sf;
- int err;
-
- if ((tw = [self keyWindow]) != nil) {
- tv = [tw toyView];
- if (angle == Clip) {
- select = [tv selectedRect];
- sf = [tv scaleFactor];
- if (sf != 1.0) {
- rct.size.width = (int)(select->size.width / sf + 0.5);
- rct.size.height = (int)(select->size.height / sf + 0.5);
- rct.origin.x = (int)(select->origin.x / sf + 0.5);
- rct.origin.y = (int)(select->origin.y / sf + 0.5);
- select = &rct;
- }
- if (select->size.width < 1.0 || select->size.height < 1.0)
- tw = nil;
- }
- }
- if (tw == nil) {
- NXBeep();
- return self;
- }
-
- cinf = [tv commonInfo];
- if (cinf->width >= MAXWidth || cinf->height >= MAXWidth
- || (angle == 45 && Width45(cinf->width, cinf->height) >= MAXWidth)) {
- errAlert([tw filename], Err_MEMORY);
- return self;
- }
- if (angle > 0) ex = "Rotate";
- else if (angle == Clip) ex = "Clip";
- else if (angle == Negative) ex = "Negative";
- else ex = "Flip";
- sprintf(fn, "%s(%s)", [tw filename], ex);
-
- if (cinf->type == Type_eps) {
- NXStream *stream;
- ToyWinEPS *newtw;
-
- if (angle == Negative) {
- errAlert([tw filename], Err_EPS_IMPL);
- return self;
- }
- stream = (angle == Clip)
- ? [(ToyWinEPS *)tw clipEPS:select error:&err]
- : [(ToyWinEPS *)tw rotateEPS:angle name:fn error:&err];
- if (stream == NULL) {
- errAlert(fn, err);
- return self;
- }
- newtw = [[ToyWinEPS alloc] init: self];
- err = [newtw drawFromFile:(const char *)fn or:stream Num:NewLoc];
- NXCloseMemory(stream, NX_FREEBUFFER);
- if (err) {
- errAlert(fn, err);
- [newtw free];
- }else
- [self newWindow: newtw];
- return self;
- }
-
- if (cinf->cspace == NX_CMYKColorSpace) {
- errAlert(fn, Err_IMPLEMENT);
- return self;
- }
-
- rep = [[tv image] bestRepresentation];
- [(NXBitmapImageRep *)rep getDataPlanes: map];
- if ((err = initGetPixel(cinf)) != 0) {
- errAlert(fn, err);
- return self;
- }
- resetPixel(map, 0);
- if ([self doBitmap:fn info:cinf to:angle rect:select] == nil)
- errAlert(fn, Err_MEMORY);
-
- return self;
- }
-
- - rotate: sender
- {
- static int tagAngles[] = { 45, 90, 270, 180 };
- return [self doRotateFlipClip: tagAngles[[sender selectedTag]]];
- }
-
- - flip: sender
- {
- static int flipkind[]
- = { Horizontal, Vertical, Negative, Clip };
- return [self doRotateFlipClip: flipkind[[sender selectedTag]]];
- }
-
- @end
-