home *** CD-ROM | disk | FTP | other *** search
- /*
- * Sample2
- *
- * A quick example of how to build a simple hook that doesn't
- * have an interface. (See GedSample for interface tips.)
- *
- * This sample just adds 1 to the value of every pixel in the
- * currently selected image (either the main buffer or the
- * brush, depending on the state of the Region cycler).
- *
- * This sample also obeys feathering.
- *
- * Written by Thomas Krehbiel, 26-Apr-94
- *
- */
-
- #include <scan/hooks.h>
- #include <clib/dos_protos.h>
- #include <clib/intuition_protos.h>
- #include <clib/graphics_protos.h>
-
-
- /* This information is required by the "start.o" startup code. */
- char *HookName = "Sample2";
-
- /* A version string so the Version command works on us. */
- char *HookVersion = "\0$VER: Sample2 2.0.2 (15.2.95)";
-
-
- /*******************************************************************
- *
- * Defines
- *
- *******************************************************************/
-
- #define MIN(a,b) ((a) < (b) ? (a) : (b))
-
-
- /*******************************************************************
- *
- * Text Array and Indexes
- *
- *******************************************************************/
-
- /* This information is required by the "start.o" startup code. */
- /* For this example, we're not doing any localization stuff. */
-
- char *HookText = "Hook_Sample2";
- int HookTextCount = 0;
- char **HookStrings[] = { NULL };
-
-
- /*******************************************************************
- *
- * Hook entry point is here.
- *
- *******************************************************************/
-
- void hook_main (int argc, char **argv)
- {
- struct Buffer *buf;
- int i, j;
- int le, te, w, h;
- UBYTE *red, *grn, *blu;
- struct Blend *blend = NULL;
- UBYTE *mask;
- short mix = 255;
-
- /*
- * Get current buffer.
- */
- if (ScanBase->sb_AreaTool == AT_BRUSH)
- buf = ScanBase->sb_Brush;
- else
- buf = ScanBase->MainBuffer;
-
- /*
- * If no buffer, complain and exit.
- */
- if (!buf) {
- SetError(ERR_NoBuffer);
- Error();
- return;
- }
-
- /*
- * Get area to be affected. If the user has defined a region,
- * then the Buffer->Mask structure defines that region. We
- * limit our processing to that region.
- */
- if (buf->Mask) {
- le = buf->Mask->OffsetX;
- te = buf->Mask->OffsetY;
- w = buf->Mask->Width;
- h = buf->Mask->Height;
-
- /*
- * If feathering is on, this function will create an 8-bit
- * mask for the region specified. It returns NULL if no
- * feathering is enabled. Note that we can only apply
- * feather IN; we cannot do feather OUT.
- */
- if (ScanBase->sb_EdgeMode == EM_FEATHERIN) {
- blend = CreateBlend(buf->Mask);
- }
- }
- else {
- le = 0;
- te = 0;
- w = buf->Width;
- h = buf->Height;
- }
-
-
- /*
- * Save the region we are about to fiddle with into an undo buffer.
- */
- SaveUndo(buf, le, te, w, h);
-
- /*
- * Start a cancel-able status bar.
- */
- BeginBar("Thingy", h, TRUE);
-
- /*
- * Loop over each scanline.
- */
- for (j = 0; j < h; j++) {
-
- /*
- * Iterate the status bar.
- */
- if (Bar(j)) {
- /* Status bar was cancelled if Bar() returns non-zero */
- RestoreUndo(FALSE); /* restore portion that was already
- modified from the undo buffer */
- break;
- }
-
- /*
- * Get a scanline of data from the buffer. Using this
- * function automatically supports vmem.
- */
- if (!GetBufLine(buf, &red, &grn, &blu, j + te)) {
- /* Failure means a vmem disk fault of some kind */
- break;
- }
-
- /*
- * Check for feathering; get pointer to current row.
- */
- if (blend) mask = blend->Blend + (j * blend->Width);
-
- for (i = 0; i < w; i++) {
-
- /*
- * Get blend value for this pixel if feathering
- * is on.
- */
- if (blend) mix = *mask++;
-
- /*
- * The CheckMask() function finds out whether the
- * given X,Y location is within the mask given.
- * Note that the coordinates passed to CheckMask()
- * are relative to the upper-left corner of the mask,
- * NOT the image.
- */
- if (CheckMask(buf->Mask, i, j)) {
- /*
- * The mixer() function is used to blend new pixels
- * into old pixels at a specified blend percentage.
- */
- red[le+i] = mixer(MIN(255, red[le+i]+1), red[le+i], mix);
- grn[le+i] = mixer(MIN(255, grn[le+i]+1), grn[le+i], mix);
- blu[le+i] = mixer(MIN(255, blu[le+i]+1), blu[le+i], mix);
- }
-
- }
-
- /*
- * After processing a scanline, we MUST use PutBufLine()
- * to put it back into the buffer. If not, then the
- * changes will not take effect for a vmem buffer.
- * PutBufLine() restores the last line read with GetBufLine().
- */
- PutBufLine(buf);
-
- }
-
- /*
- * Get rid of the status bar. (Don't forget this or the
- * interface will be locked out.)
- */
- EndBar(NULL);
-
- /*
- * Delete the blend plane we created.
- */
- if (blend) DeleteBlend(blend);
-
- /*
- * Redraw the image to show what we did.
- */
- RedrawFull();
- }
-