home *** CD-ROM | disk | FTP | other *** search
/ HyperLib 1997 Winter - Disc 1 / HYPERLIB-1997-Winter-CD1.ISO.7z / HYPERLIB-1997-Winter-CD1.ISO / 第1特集Plug-in / Photoshop / Plug-in_Kit_2.5.1.sit / Plug-in_Kit_2.5.1 / Code / Dissolve.c < prev    next >
Text File  |  1994-04-12  |  9KB  |  477 lines

  1. /*
  2.     File: Dissolve.c
  3.  
  4.     Copyright 1990 by Thomas Knoll.
  5.     Copyright 1993 by Adobe Systems, Inc.
  6.  
  7.     C source file for Dissolve example.
  8. */
  9.  
  10. #include <Types.h>
  11. #include <Memory.h>
  12. #include <Resources.h>
  13. #include <QuickDraw.h>
  14. #include <Dialogs.h>
  15. #include <OSUtils.h>
  16. #include <Packages.h>
  17. #include <Errors.h>
  18. #include <ToolUtils.h>
  19.  
  20. #include "PITypes.h"
  21. #include "PIGeneral.h"
  22. #include "PIFilter.h"
  23.  
  24. #include "DialogUtilities.h"
  25. #include "PIUtilities.h"
  26.  
  27. #ifdef THINK_C
  28.  
  29. #define ENTRYPOINT main
  30.  
  31. #endif
  32.  
  33. /*****************************************************************************/
  34.  
  35. typedef struct TParameters
  36.     {
  37.     short percent;
  38.     } TParameters, *PParameters, **HParameters;
  39.  
  40. /*****************************************************************************/
  41.  
  42. typedef struct Globals
  43.     {
  44.     short result;
  45.     FilterRecord *stuff;
  46.     } Globals, *GPtr, **GHdl;
  47.     
  48. #define gResult ((**globals).result)
  49. #define gStuff  ((**globals).stuff)
  50.  
  51. /*****************************************************************************/
  52.  
  53. void InitGlobals (GHdl globals);
  54.  
  55. void DoAbout (GHdl globals);
  56. void DoParameters (GHdl globals);
  57. void DoPrepare (GHdl globals);
  58. void DoStart (GHdl globals);
  59. void DoContinue (GHdl globals);
  60. void DoFinish (GHdl globals);
  61.  
  62. /*****************************************************************************/
  63.  
  64. /* All calls to the plug-in module come through this routine. It must be
  65.    placed first in the resource. To achieve this, most development systems
  66.    require that this be the first routine in the source. */
  67.  
  68. pascal void ENTRYPOINT (short selector,
  69.                         FilterRecord *stuff,
  70.                         long *data,
  71.                         short *result)
  72.     {
  73.     
  74.     GHdl globals;
  75.     
  76.     if (!*data)
  77.         {
  78.  
  79.         *data = (long) NewHandle (sizeof (Globals));
  80.         
  81.         if (!*data)
  82.             {
  83.             *result = memFullErr;
  84.             return;
  85.             }
  86.             
  87.         InitGlobals ((GHdl) *data);
  88.         
  89.         }
  90.         
  91.     globals = (GHdl) *data;
  92.         
  93.     gStuff = stuff;
  94.     gResult = noErr;
  95.         
  96.     switch (selector)
  97.         {
  98.         
  99.         case filterSelectorAbout:
  100.             DoAbout (globals);
  101.             break;
  102.             
  103.         case filterSelectorParameters:
  104.             DoParameters (globals);
  105.             break;
  106.             
  107.         case filterSelectorPrepare:
  108.             DoPrepare (globals);
  109.             break;
  110.         
  111.         case filterSelectorStart:
  112.             DoStart (globals);
  113.             break;
  114.         
  115.         case filterSelectorContinue:
  116.             DoContinue (globals);
  117.             break;
  118.         
  119.         case filterSelectorFinish:
  120.             DoFinish (globals);
  121.             break;
  122.             
  123.         default:
  124.             gResult = filterBadParameters;
  125.         
  126.         }
  127.         
  128.     *result = gResult;
  129.         
  130.     }
  131.  
  132. /*****************************************************************************/
  133.  
  134. void InitGlobals (GHdl globals)
  135.     {
  136.     
  137.     #pragma unused (globals)
  138.     
  139.     /* None of the globals requires initialization. */
  140.     
  141.     }
  142.  
  143. /*****************************************************************************/
  144.  
  145. /* Displays the about dialog box for the plug-in module. */
  146.  
  147. void DoAbout (GHdl globals)
  148.     {
  149.  
  150.     #pragma unused (globals)
  151.     
  152.     #define dialogID 16000
  153.     
  154.     ShowAbout (dialogID);
  155.  
  156.     #undef dialogID
  157.  
  158.     }
  159.  
  160. /*****************************************************************************/
  161.  
  162. static ProcessEventProc gProcessEvent = NULL;
  163.  
  164. MACPASCAL void ProcessEvent(void *event)
  165.     {
  166.  
  167.     if (gProcessEvent != NULL)
  168.         {
  169.  
  170. #ifdef __powerc
  171.  
  172.         CallUniversalProc((UniversalProcPtr)gProcessEvent, uppProcessEventProcInfo, event);
  173.  
  174. #else
  175.  
  176.         (*gProcessEvent)(event);
  177.  
  178. #endif
  179.  
  180.         }
  181.  
  182.     }
  183.  
  184.  
  185. /*****************************************************************************/
  186.  
  187. /* Asks the user for the plug-in filter module's parameters. Note that
  188.    the image size information is not yet defined at this point. Also, do
  189.    not assume that the calling program will call this routine every time the
  190.    filter is run (it may save the data held by the parameters handle in
  191.    a macro file). */
  192.  
  193. void DoParameters (GHdl globals)
  194.  
  195.     {
  196.  
  197.     #define dialogID    16001
  198.     #define hookItem    3
  199.     #define percentItem 4
  200.     
  201.     long x;
  202.     short item;
  203.     DialogPtr dp;
  204.     DialogTHndl dt;
  205.  
  206.     if (!gStuff->parameters)
  207.         {
  208.  
  209.         gStuff->parameters = NewHandle ((long) sizeof (TParameters));
  210.  
  211.         if (!gStuff->parameters)
  212.             {
  213.             gResult = memFullErr;
  214.             return;
  215.             }
  216.  
  217.         ((PParameters) *gStuff->parameters)->percent = 50;
  218.  
  219.         }
  220.  
  221.     dt = (DialogTHndl) GetResource ('DLOG', dialogID);
  222.     HNoPurge ((Handle) dt);
  223.     
  224.     CenterDialog (dt);
  225.     SetUpMoveableModal (dt, gStuff->hostSig);
  226.  
  227.     dp = GetNewDialog (dialogID, nil, (WindowPtr) -1);
  228.  
  229.     SetOutlineOKHook (dp, hookItem);
  230.     
  231.     StuffNumber (dp,
  232.                  percentItem,
  233.                  ((PParameters) *gStuff->parameters)->percent);
  234.     
  235.     SetArrowCursor ();
  236.  
  237.     SelectTextItem (dp, percentItem); 
  238.  
  239.     do
  240.         {
  241.  
  242.         gProcessEvent = gStuff->processEvent;
  243.  
  244.         MoveableModalDialog (dp, &ProcessEvent, nil, &item);
  245.  
  246.         gProcessEvent = NULL;
  247.  
  248.         if (item == ok)
  249.             {
  250.  
  251.             if (!FetchNumber (dp, percentItem, 1, 99, &x))
  252.                 item = 0;
  253.  
  254.             }
  255.  
  256.         }
  257.     while (item != ok && item != cancel);
  258.  
  259.     DisposDialog (dp);
  260.     HPurge ((Handle) dt);
  261.  
  262.     if (item == cancel)
  263.         {
  264.         gResult = 1;
  265.         return;
  266.         }
  267.  
  268.     ((PParameters) *gStuff->parameters)->percent = x;
  269.  
  270.     #undef dialogID
  271.     #undef hookItem
  272.     #undef percentItem
  273.  
  274.     }
  275.  
  276. /*****************************************************************************/
  277.  
  278. /* Prepare to filter an image.    If the plug-in filter needs a large amount
  279.    of buffer memory, this routine should set the bufferSpace field to the
  280.    number of bytes required. */
  281.  
  282. void DoPrepare (GHdl globals)
  283.     {
  284.     
  285.     gStuff->bufferSpace = 0;
  286.     
  287.     }
  288.  
  289. /*****************************************************************************/
  290.  
  291. void DoInitialRect (GHdl globals);
  292. Boolean DoNextRect (GHdl globals);
  293.  
  294. void DoFilterRect (GHdl globals);
  295.  
  296. /*****************************************************************************/
  297.  
  298. /* Requests pointer to the first part of the image to be filtered. */
  299.  
  300. void DoStart (GHdl globals)
  301.     {
  302.     
  303.     DoInitialRect (globals);
  304.  
  305.     }
  306.  
  307. /*****************************************************************************/
  308.  
  309. /* Filters the area and requests the next area. */
  310.  
  311. void DoContinue (GHdl globals)
  312.     {
  313.     
  314.     if (TestAbort ())
  315.         {
  316.         gResult = 1;
  317.         return;
  318.         }
  319.         
  320.     DoFilterRect (globals);
  321.     
  322.     if (!DoNextRect (globals))
  323.         {
  324.         SetRect (&gStuff->inRect, 0, 0, 0, 0);
  325.         SetRect (&gStuff->outRect, 0, 0, 0, 0);
  326.         }
  327.  
  328.     }
  329.  
  330. /*****************************************************************************/
  331.  
  332. /* Requests first part of the image to be filtered. */
  333.  
  334. void DoInitialRect (GHdl globals)
  335.     {
  336.  
  337.     gStuff->inRect          = gStuff->filterRect;
  338.     gStuff->inRect.bottom = gStuff->inRect.top + 1;
  339.  
  340.     gStuff->inLoPlane = 0;
  341.     gStuff->inHiPlane = gStuff->planes - 1;
  342.     
  343.     gStuff->outRect = gStuff->inRect;
  344.  
  345.     gStuff->outLoPlane = gStuff->inLoPlane;
  346.     gStuff->outHiPlane = gStuff->inHiPlane;
  347.  
  348.     }
  349.  
  350. /*****************************************************************************/
  351.  
  352. /* Request the next area. */
  353.  
  354. Boolean DoNextRect (GHdl globals)
  355.     {
  356.  
  357.     gStuff->inRect.top      = gStuff->inRect.top      + 1;
  358.     gStuff->inRect.bottom = gStuff->inRect.bottom + 1;
  359.     
  360.     gStuff->outRect = gStuff->inRect;
  361.  
  362.     return gStuff->inRect.top < gStuff->filterRect.bottom;
  363.  
  364.     }
  365.  
  366. /*****************************************************************************/
  367.  
  368. /* Filter the area. */
  369.  
  370. void DoFilterRect (GHdl globals)
  371.     {
  372.  
  373.     short rand;
  374.     short count;
  375.     short plane;
  376.     short percent;
  377.     unsigned char *srcPtr;
  378.     unsigned char *dstPtr;
  379.  
  380.     UpdateProgress ((long) gStuff->inRect.top - gStuff->filterRect.top,
  381.                     (long) gStuff->filterRect.bottom - gStuff->filterRect.top);
  382.  
  383.     percent = ((PParameters) *gStuff->parameters)->percent;
  384.  
  385.     srcPtr = (unsigned char *) gStuff->inData;
  386.     dstPtr = (unsigned char *) gStuff->outData;
  387.  
  388.     count = gStuff->filterRect.right - gStuff->filterRect.left;
  389.  
  390.     while (count--)
  391.         {
  392.  
  393.         rand = Random ();
  394.         rand = (rand < 0 ? -rand : rand);
  395.  
  396.         if (rand % 100 < percent)
  397.             {
  398.  
  399.             for (plane = 0; plane < gStuff->planes; ++plane)
  400.                 *(dstPtr++) = plane < 4 ? gStuff->backColor [plane]
  401.                                         : 255;
  402.  
  403.             srcPtr += gStuff->planes;
  404.  
  405.             }
  406.  
  407.         else
  408.             for (plane = 0; plane < gStuff->planes; ++plane)
  409.                 *(dstPtr++) = *(srcPtr++);
  410.  
  411.         }
  412.  
  413.     }
  414.  
  415. /*****************************************************************************/
  416.  
  417. /* This routine will always be called if DoStart does not return an error
  418.    (even if DoContinue returns an error or the user aborts the operation).
  419.    This allows the module to perform any needed cleanup.  None is required
  420.    in this example. */
  421.  
  422. void DoFinish (GHdl globals)
  423.     {
  424.     
  425.     /* We will attempt to add a resource showing that we made this change.
  426.        Unfortunately, we will not be able to remove this resource if the
  427.        user chooses undo.  This could change in the future, so do not
  428.        count on it. */
  429.     
  430.     Str255 string;
  431.     short stringLength;
  432.     short numLength;
  433.     Handle h;
  434.     
  435.     if (!ResourceProcsAvailable (NULL))
  436.         return;
  437.         
  438.     GetIndString (string, 16000, 1);
  439.         
  440.     stringLength = (unsigned char) (string [0]);
  441.     
  442.     h = PINewHandle (stringLength);
  443.     
  444.     if (!h)
  445.         return;
  446.         
  447.     BlockMove (&(string [1]), PILockHandle (h, FALSE), stringLength); 
  448.  
  449.     PIUnlockHandle (h);
  450.     
  451.     NumToString (((PParameters) *gStuff->parameters)->percent, string);
  452.     
  453.     numLength = (unsigned char) string [0];
  454.     
  455.     if (PISetHandleSize (h, stringLength + numLength + 1) == noErr)
  456.         {
  457.         
  458.         BlockMove (&(string [1]),
  459.                    PILockHandle (h, FALSE) + stringLength,
  460.                    numLength);
  461.         
  462.         PIUnlockHandle (h);
  463.         
  464.         stringLength += numLength;
  465.         
  466.         (*h) [stringLength] = '%';
  467.         
  468.         (void) AddPIResource ('hist', h);
  469.         
  470.         }
  471.         
  472.     PIDisposeHandle (h);
  473.     
  474.     }
  475.  
  476. /*****************************************************************************/
  477.