home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 3 / goldfish_volume_3.bin / files / gfx / misc / imagefx_sdk / sas / examples / hooks / sample2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-15  |  5.1 KB  |  207 lines

  1. /*
  2.  * Sample2
  3.  *
  4.  * A quick example of how to build a simple hook that doesn't
  5.  * have an interface.  (See GedSample for interface tips.)
  6.  *
  7.  * This sample just adds 1 to the value of every pixel in the
  8.  * currently selected image (either the main buffer or the
  9.  * brush, depending on the state of the Region cycler).
  10.  *
  11.  * This sample also obeys feathering.
  12.  *
  13.  * Written by Thomas Krehbiel, 26-Apr-94
  14.  *
  15.  */
  16.  
  17. #include <scan/hooks.h>
  18. #include <clib/dos_protos.h>
  19. #include <clib/intuition_protos.h>
  20. #include <clib/graphics_protos.h>
  21.  
  22.  
  23. /* This information is required by the "start.o" startup code. */
  24. char *HookName = "Sample2";
  25.  
  26. /* A version string so the Version command works on us. */
  27. char *HookVersion = "\0$VER: Sample2 2.0.2 (15.2.95)";
  28.  
  29.  
  30. /*******************************************************************
  31.  *
  32.  *  Defines
  33.  *
  34.  *******************************************************************/
  35.  
  36. #define MIN(a,b)     ((a) < (b) ? (a) : (b))
  37.  
  38.  
  39. /*******************************************************************
  40.  *
  41.  *  Text Array and Indexes
  42.  *
  43.  *******************************************************************/
  44.  
  45. /* This information is required by the "start.o" startup code. */
  46. /* For this example, we're not doing any localization stuff. */
  47.  
  48. char *HookText = "Hook_Sample2";
  49. int   HookTextCount = 0;
  50. char **HookStrings[] = { NULL };
  51.  
  52.  
  53. /*******************************************************************
  54.  *
  55.  *  Hook entry point is here.
  56.  *
  57.  *******************************************************************/
  58.  
  59. void hook_main (int argc, char **argv)
  60. {
  61.    struct Buffer *buf;
  62.    int i, j;
  63.    int le, te, w, h;
  64.    UBYTE *red, *grn, *blu;
  65.    struct Blend *blend = NULL;
  66.    UBYTE *mask;
  67.    short mix = 255;
  68.  
  69.    /*
  70.     * Get current buffer.
  71.     */
  72.    if (ScanBase->sb_AreaTool == AT_BRUSH)
  73.       buf = ScanBase->sb_Brush;
  74.    else
  75.       buf = ScanBase->MainBuffer;
  76.  
  77.    /*
  78.     * If no buffer, complain and exit.
  79.     */
  80.    if (!buf) {
  81.       SetError(ERR_NoBuffer);
  82.       Error();
  83.       return;
  84.    }
  85.  
  86.    /*
  87.     * Get area to be affected.  If the user has defined a region,
  88.     * then the Buffer->Mask structure defines that region.  We
  89.     * limit our processing to that region.
  90.     */
  91.    if (buf->Mask) {
  92.       le = buf->Mask->OffsetX;
  93.       te = buf->Mask->OffsetY;
  94.       w  = buf->Mask->Width;
  95.       h  = buf->Mask->Height;
  96.  
  97.       /*
  98.        * If feathering is on, this function will create an 8-bit
  99.        * mask for the region specified.  It returns NULL if no
  100.        * feathering is enabled.  Note that we can only apply
  101.        * feather IN; we cannot do feather OUT.
  102.        */
  103.       if (ScanBase->sb_EdgeMode == EM_FEATHERIN) {
  104.          blend = CreateBlend(buf->Mask);
  105.       }
  106.    }
  107.    else {
  108.       le = 0;
  109.       te = 0;
  110.       w  = buf->Width;
  111.       h  = buf->Height;
  112.    }
  113.  
  114.  
  115.    /*
  116.     * Save the region we are about to fiddle with into an undo buffer.
  117.     */
  118.    SaveUndo(buf, le, te, w, h);
  119.  
  120.    /*
  121.     * Start a cancel-able status bar.
  122.     */
  123.    BeginBar("Thingy", h, TRUE);
  124.  
  125.    /*
  126.     * Loop over each scanline.
  127.     */
  128.    for (j = 0; j < h; j++) {
  129.  
  130.       /*
  131.        * Iterate the status bar.
  132.        */
  133.       if (Bar(j)) {
  134.          /* Status bar was cancelled if Bar() returns non-zero */
  135.          RestoreUndo(FALSE);  /* restore portion that was already
  136.                                  modified from the undo buffer */
  137.          break;
  138.       }
  139.  
  140.       /*
  141.        * Get a scanline of data from the buffer.  Using this
  142.        * function automatically supports vmem.
  143.        */
  144.       if (!GetBufLine(buf, &red, &grn, &blu, j + te)) {
  145.          /* Failure means a vmem disk fault of some kind */
  146.          break;
  147.       }
  148.  
  149.       /*
  150.        * Check for feathering; get pointer to current row.
  151.        */
  152.       if (blend) mask = blend->Blend + (j * blend->Width);
  153.  
  154.       for (i = 0; i < w; i++) {
  155.  
  156.          /*
  157.           * Get blend value for this pixel if feathering
  158.           * is on.
  159.           */
  160.          if (blend) mix = *mask++;
  161.  
  162.          /*
  163.           * The CheckMask() function finds out whether the
  164.           * given X,Y location is within the mask given.
  165.           * Note that the coordinates passed to CheckMask()
  166.           * are relative to the upper-left corner of the mask,
  167.           * NOT the image.
  168.           */
  169.          if (CheckMask(buf->Mask, i, j)) {
  170.             /*
  171.              * The mixer() function is used to blend new pixels
  172.              * into old pixels at a specified blend percentage.
  173.              */
  174.             red[le+i] = mixer(MIN(255, red[le+i]+1), red[le+i], mix);
  175.             grn[le+i] = mixer(MIN(255, grn[le+i]+1), grn[le+i], mix);
  176.             blu[le+i] = mixer(MIN(255, blu[le+i]+1), blu[le+i], mix);
  177.          }
  178.  
  179.       }
  180.  
  181.       /*
  182.        * After processing a scanline, we MUST use PutBufLine()
  183.        * to put it back into the buffer.  If not, then the
  184.        * changes will not take effect for a vmem buffer.
  185.        * PutBufLine() restores the last line read with GetBufLine().
  186.        */
  187.       PutBufLine(buf);
  188.  
  189.    }
  190.  
  191.    /*
  192.     * Get rid of the status bar.  (Don't forget this or the
  193.     * interface will be locked out.)
  194.     */
  195.    EndBar(NULL);
  196.  
  197.    /*
  198.     * Delete the blend plane we created.
  199.     */
  200.    if (blend) DeleteBlend(blend);
  201.  
  202.    /*
  203.     * Redraw the image to show what we did.
  204.     */
  205.    RedrawFull();
  206. }
  207.