home *** CD-ROM | disk | FTP | other *** search
- /*
- * negative.c - Does a simple negative in Imagemaster
- */
-
- #include <stdio.h>
-
- /*
- * Each individual buffer has the following struture for use in a
- * Public Interface Module. Note that the "mask" pointer is usually
- * NULL; it is only there when the buffer is non-rectangular, for
- * instance when the user has cut out a clip using freehand.
- * if it is there, you are well advised to use it. There is data
- * available in the buffer where the mask is zero, but it is
- * hidden from the user and processing in it is a waste of time.
- * Although all three RGB pointers should be there, you should
- * still check them for safety's sake.
- */
- struct jackinbuff
- {
- unsigned char *red; /* points to red component of buffer */
- unsigned char *green; /* points to green component of buffer */
- unsigned char *blue; /* points to blue component of buffer */
- unsigned char *mask; /* points to local mask, IF there is one */
- unsigned short x; /* X size of buffer (pixels per line) */
- unsigned short y; /* Y size of buffer (pixels per column) */
- };
-
- /*
- * This is the main "handle" you get from the ARexx "jackin" command.
- * Note that any, or ALL of the buffer pointers may be NULL, and you
- * MUST check them for validity before using them or you may blow up
- * the system. Macros may be invoked without a single buffer available.
- */
- struct jackina
- {
- struct jackinbuff *primary; /* current working buffer */
- struct jackinbuff *secondary; /* compositing buffer */
- struct jackinbuff *undo; /* undo buffer */
- struct jackinbuff *blend; /* blend buffer */
- struct jackinbuff *brush; /* brush buffer */
- unsigned char *mask; /* working mask (use WITH local masks) */
- char jack[4]; /* ID for sanity chk: 'J' 'A' 'C' 'K' */
- long showscr; /* points to control panel screen */
- unsigned char pname[4]; /* 'IM'00 'IP'00 or 'IMFC' - sanity chk */
- short ver[2]; /* version:revision numbers */
- };
-
- int main(argc,argv)
- int argc;
- char *argv[];
- {
- unsigned int x,y,xw,yw,offset,yoffset;
- unsigned char rr,gg,bb;
- unsigned char *mask;
- unsigned char *lmask;
- unsigned char *rbu;
- unsigned char *gbu;
- unsigned char *bbu;
- short cancel;
- struct jackina *jackins;
-
- if (argc <= 1)
- {
- imes("NEGATIVE <pointer to IM jackin structure>",
- "No pointer argument supplied!"); /* ARexx problem? */
- return(1);
- }
- else
- {
- sscanf(argv[1],"%x",(int*)&jackins);
- }
-
- if (jackins == 0)
- {
- imes("NEGATIVE : Argument is ZERO!",0); /* ARexx problem? */
- return(1);
- }
-
- if (jackins->jack[0] != 'J' ||
- jackins->jack[1] != 'A' ||
- jackins->jack[2] != 'C' ||
- jackins->jack[3] != 'K' )
- {
- imes("NEGATIVE : Problem with information", /* VERY scary! */
- "passed from image processor!");
- return(1);
- }
- if (beginvbars(jackins->showscr)) /* open communications to panel */
- {
- imes("Unable to open Progress Communication!",0); /* scary! */
- return(1);
- }
- /*
- * Up to this point, if there is a problem, "imes()" will send its
- * output to the STDOUT stream; we were not certain that we were
- * successfully linked to the image processor until now. From now on,
- * messages from "imes()" will appear upon the user's control panel.
- */
- if (jackins->primary == NULL) /* if no primary buffer */
- {
- imes("NEGATIVE : Primary buffer is NULL!",0); /* ok, but silly */
- return(1);
- }
- mask = jackins->mask;
- if (jackins->mask == NULL) /* if no mask available */
- {
- imes("NEGATIVE : No area selection mask found!",0); /* scary! */
- return(1);
- }
- xw = jackins->primary->x;
- yw = jackins->primary->y;
- if (xw == 0 || yw == 0) /* if X:Y size of primary is insane */
- {
- imes("NEGATIVE : Primary buffer is Empty!",0); /* scary! */
- return(1);
- }
- rbu = jackins->primary->red;
- gbu = jackins->primary->green;
- bbu = jackins->primary->blue;
- lmask = jackins->primary->mask; /* this can be NULL - we check later */
- if ((rbu==NULL) || (gbu==NULL) || (bbu==NULL)) /* any pointer missing? */
- {
- imes("NEGATIVE : Primary buffer is corrupted!",0); /* scary! */
- return(1);
- }
- /*
- * Actual operation is performed here
- */
- if (progressaset(yw,"-Negative-")) /* open progress bar */
- {
- imes("Cannot open progress bar!",0);
- return(1);
- }
- cancel = 0;
- for (y=0; y<yw; y++) /* for each scan line of the image */
- {
- yoffset = y * xw; /* make address offset - saves lots of multiplies */
- for (x=0; x<xw; x++) /* for each pixel in the scan line */
- {
- offset = yoffset + x;
- if (lmask) /* if there is a local mask */
- {
- if (mask[offset] & lmask[offset]) /* selected & selectable? */
- {
- rr = *(rbu+offset); /* get the pixel RGB data */
- gg = *(gbu+offset);
- bb = *(bbu+offset);
- *(rbu+offset) = 255 - rr; /* perform color negative */
- *(gbu+offset) = 255 - gg;
- *(bbu+offset) = 255 - bb;
- }
- }
- else /* there was no local mask - just use main mask */
- {
- if (mask[offset]) /* selected? */
- {
- rr = *(rbu+offset); /* get the pixel RGB data */
- gg = *(gbu+offset);
- bb = *(bbu+offset);
- *(rbu+offset) = 255 - rr; /* perform color negative */
- *(gbu+offset) = 255 - gg;
- *(bbu+offset) = 255 - bb;
- }
- }
- }
- if (progressupd(y)) /* show progress, look for press of CLOSE gadget */
- {
- if (y != yw) /* if we're not already done */
- {
- cancel = 1; /* indicate user forced exit */
- y = yw; /* force structured exit from processing loop */
- }
- }
- }
- progressend(); /* close progress bar */
- if (cancel) /* ack the press of close gadget */
- {
- imes("Operation Cancelled at User's Request",0);
- return(1); /* return not ok - operation incomplete */
- }
- endvbars(); /* close ALL references to image processor screen */
- return(0);
- }
-
-