home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
594a.lha
/
IP_Interface_example
/
negative.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-03
|
7KB
|
185 lines
/*
* 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);
}