home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / netds / rpc / wintyp / remote.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-23  |  10.4 KB  |  286 lines

  1. /*************************************************************************
  2.                 Copyright Microsoft Corp. 1992-1996
  3.                     Remote Machine WinType sample
  4.  
  5.     FILE        :   REMOTE.C
  6.  
  7.     PURPOSE     :   The actual functions on the server side of the RPC 
  8.                     distributed application wintyp that are called from 
  9.                     the client side.
  10.  
  11.     COMMENTS    :   This sample is made to demonstrate the passing of a 
  12.                     Window Type from the client to the server. The 
  13.                     colordepth in the edge detection funciton is limited
  14.                     to 256 color because of the simpler algorithm
  15.  
  16. *************************************************************************/
  17. #include "wintyp.h"         // Generated by the MIDL compiler
  18. #include "common.h"         // Common definitions for all files
  19. #include <windows.h>        // All windows programs must include this file
  20.  
  21. #define THRESHOLD   75      // Threshold value in findedges function
  22.  
  23. // Local procedures used only within this file
  24. BYTE **Get2DPointer(BYTE *, LONG, LONG);
  25. void FindEdges(BYTE **, BYTE **, LONG, int, int);
  26. void FlipImage(BYTE **, BYTE **, LONG, int, int);
  27.  
  28. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  29. // Function     :   BOOL ChangeBitmapRemote ()
  30. // Desc.        :   This function is called from the client side. First it 
  31. //                  allocates space for the data in the image passed from 
  32. //                  the client. Then it will analyze the function call, 
  33. //                  and perform a findedge, or flipimage operation on the 
  34. //                  bitmap passed from the client.
  35. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  36. BOOL ChangeBitmapRemote(unsigned short nAction, HBITMAP *hBM)
  37. {
  38.     BITMAP sBM;              // A structure to load the bitmap data into
  39.     BOOL   bRetValue;        // The value to return from this function
  40.     BYTE   *pbOldBitmapBits, // Buffer to hold the old values of the bitmap
  41.            *pbNewBitmapBits, // Buffer to hold the new values of the bitmap
  42.            **pbOldImage,     // 2D-pointer to the old image 
  43.            **pbNewImage;     // 2D-pointer to the new image
  44.     long   nImageSize;       // The size of the image in bytes
  45.     
  46.  
  47.     _tprintf(TEXT("In the remote procedure \'ChangeBitmapRemote\'\n"));
  48.     // Obtain information about the BITMAP from the handle to the bitmap
  49.     GetObject(*hBM, sizeof(BITMAP), (LPVOID) &sBM);
  50.  
  51.     // Calculate the total number of bytes the image occupies
  52.     nImageSize = sBM.bmHeight * sBM.bmWidthBytes;
  53.     
  54.     // Allocate memory for the buffers to store the image data in
  55.     if (NULL == (pbOldBitmapBits = (BYTE *) malloc (nImageSize)))
  56.     {
  57.         _tprintf(TEXT("Memory allocation error"));
  58.         return FALSE;
  59.     }
  60.     
  61.     if (NULL == (pbNewBitmapBits = (BYTE *) malloc (nImageSize)))
  62.     {
  63.         _tprintf(TEXT("Memory allocation error"));
  64.         return FALSE;
  65.     }
  66.     
  67.     // Get the data from the image, and fill into the old image buffer
  68.     GetBitmapBits(*hBM, nImageSize, (LPVOID) pbOldBitmapBits);
  69.     
  70.     // Create 2D-array pointers to the image data for easier acces
  71.     if(NULL == (pbOldImage = Get2DPointer(pbOldBitmapBits, 
  72.         sBM.bmHeight, sBM.bmWidthBytes)))
  73.     {
  74.         return FALSE;
  75.     }
  76.     if(NULL == (pbNewImage = Get2DPointer(pbNewBitmapBits, 
  77.         sBM.bmHeight, sBM.bmWidthBytes)))
  78.     {
  79.         return FALSE;
  80.     }
  81.  
  82.  
  83.     switch(nAction)
  84.     {
  85.         case FINDEDGE :
  86.             FindEdges(pbOldImage, 
  87.                     pbNewImage, 
  88.                     nImageSize, 
  89.                     sBM.bmWidth, 
  90.                     sBM.bmHeight);
  91.             
  92.             // Copy the new image data into the bitmap to return to client
  93.             SetBitmapBits(*hBM, nImageSize, (const void *) pbNewBitmapBits);
  94.             bRetValue = TRUE;
  95.             break;
  96.  
  97.         case FLIPIMAGE:
  98.             FlipImage(pbOldImage, 
  99.                     pbNewImage, 
  100.                     nImageSize, 
  101.                     sBM.bmWidthBytes, 
  102.                     sBM.bmHeight);
  103.             
  104.             // Copy the new image data into the bitmap to return to client
  105.             SetBitmapBits(*hBM, nImageSize, 
  106.                 (const void *) pbNewBitmapBits);
  107.             bRetValue = TRUE;
  108.             break;
  109.  
  110.         default :
  111.             bRetValue = FALSE;
  112.     }
  113.  
  114.     // Deallocate the memory used for the imagebuffers and the 2D-pointers
  115.     free(pbOldBitmapBits);
  116.     free(pbNewBitmapBits);
  117.     free(pbOldImage);
  118.     free(pbNewImage);
  119.  
  120.     _tprintf(TEXT("Leaving the remote procedure \'ChangeBitmapRemote\'\n"));
  121.     
  122.     return bRetValue;
  123. }
  124.  
  125.  
  126. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  127. // Function     :   void FindEdges ()
  128. // Desc.        :   This function finds the edges in a given image by 
  129. //                  using the Sobel edge operators. The image will be 
  130. //                  changed to the edges corresponding to the boundaries 
  131. //                  in it                                  
  132. // Comments     :   The algorithm used works best on grayscale images, but 
  133. //                  it should produce acceptable results on a 256-color 
  134. //                  image as well
  135. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  136. void FindEdges(BYTE **pbOldImage,       // 2D-pointer to existing image
  137.                BYTE **pbNewImage,       // 2D-pointer to the new image
  138.                LONG nImageSize,         // The size of the image in bytes
  139.                int nWidth,              // The width of the image
  140.                int nHeight)             // The Height of the image
  141. {
  142.     int
  143.         nIdx1, nIdx2,   // Counters in loops 
  144.         nGx, nGy,       // Values found by applying the masks Gx and Gy 
  145.         nMax = 0;       // Max value for the edge
  146.     
  147.     
  148.  
  149.     
  150.     // Go through every pixel in the image, and find the edges 
  151.     for (nIdx1 = 1; nIdx1 < (nHeight - 1); nIdx1++)
  152.     {
  153.         for (nIdx2 = 1; nIdx2 < (nWidth - 1); nIdx2++)
  154.         {
  155.             // Find Gx 
  156.             nGx =(( (int)pbOldImage[nIdx1+1][nIdx2-1] + 
  157.                   2*(int)pbOldImage[nIdx1+1][nIdx2]   + 
  158.                     (int)pbOldImage[nIdx1+1][nIdx2+1]  )
  159.                     -   
  160.                  (  (int)pbOldImage[nIdx1-1][nIdx2-1] + 
  161.                   2*(int)pbOldImage[nIdx1-1][nIdx2]   + 
  162.                     (int)pbOldImage[nIdx1-1][nIdx2+1]  ))  / 8;
  163.  
  164.             // Find Gy 
  165.             nGy =(( (int)pbOldImage[nIdx1-1][nIdx2+1] + 
  166.                   2*(int)pbOldImage[nIdx1][nIdx2+1]   + 
  167.                     (int)pbOldImage[nIdx1+1][nIdx2+1]  )
  168.                     -
  169.                  (  (int)pbOldImage[nIdx1-1][nIdx2-1] + 
  170.                   2*(int)pbOldImage[nIdx1][nIdx2-1]   + 
  171.                     (int)pbOldImage[nIdx1+1][nIdx2-1]  ))  / 8;
  172.  
  173.             // Enter value into the new image
  174.             pbNewImage[nIdx1][nIdx2] = (BYTE)((abs(nGx) + abs(nGy))/2);
  175.         }
  176.     }
  177.  
  178.  
  179.     // Find the max value 
  180.     for (nIdx1 = 1; nIdx1 < (nHeight-1); nIdx1++)
  181.     {
  182.         for (nIdx2 = 0; nIdx2 < nWidth; nIdx2++)
  183.         {
  184.             if (pbNewImage[nIdx1][nIdx2] > nMax)
  185.             {
  186.                 nMax = pbNewImage[nIdx1][nIdx2];
  187.             }
  188.         }
  189.     }
  190.  
  191.     // Normalize every point in the image 
  192.     for (nIdx1 = 1; nIdx1 < (nHeight-1); nIdx1++)
  193.     {
  194.         for (nIdx2 = 0; nIdx2 < nWidth; nIdx2++)
  195.         {
  196.             pbNewImage[nIdx1][nIdx2]=(pbNewImage[nIdx1][nIdx2] * 255)/nMax;
  197.         }
  198.     }
  199.     
  200.     // Now set every pixel value that is less than a threshold to 0, and
  201.     // the rest to 255
  202.     for (nIdx1 = 1; nIdx1 < (nHeight-1); nIdx1++)
  203.     {
  204.         for (nIdx2 = 0; nIdx2 < nWidth; nIdx2++)
  205.         {
  206.             if(pbNewImage[nIdx1][nIdx2] > THRESHOLD)
  207.             {
  208.                 pbNewImage[nIdx1][nIdx2] = 255;
  209.             }
  210.             else 
  211.             {
  212.                 pbNewImage[nIdx1][nIdx2] = 0;
  213.             }
  214.         }
  215.     }
  216.     
  217. }
  218.  
  219.  
  220. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  221. // Function     :   void FlipImage ()
  222. // Desc.        :   This function will flip the image upside down
  223. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  224. void FlipImage(BYTE **pbOldImage,   // 2D-pointer to existing image
  225.                BYTE **pbNewImage,   // 2D-pointer to the new image
  226.                LONG nImageSize,     // The size of the image in bytes
  227.                int nWidth,          // The width of the image
  228.                int nHeight)         // The Height of the image
  229. {
  230.     int     nIdx1, nIdx2;                   // Counters in loops 
  231.  
  232.     // Copy the old image, line by line, into the new image
  233.     for (nIdx1 = 0; nIdx1 < nHeight; nIdx1++)
  234.     {
  235.         for (nIdx2 = 0; nIdx2 < nWidth; nIdx2++)
  236.         {
  237.             pbNewImage[nHeight - nIdx1 - 1][nIdx2] = 
  238.                 pbOldImage[nIdx1][nIdx2];
  239.         }
  240.     }
  241.  
  242. }
  243.  
  244. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  245. // Function :   Get2DPointer(BITMAP *)
  246. // Purpose  :   This procedure will get a 2D-pointer to the data in the 
  247. //              bitmap, which is much easier to work with than a single 
  248. //              pointer.
  249. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  250. BYTE **Get2DPointer(BYTE *pbBuffer, LONG nHeight, LONG nWidthBytes)
  251. {
  252.     BYTE **pbRetValue;        // The return value
  253.     int nIdx;
  254.  
  255.     if (NULL == (pbRetValue = (BYTE **) malloc (nHeight * sizeof(BYTE *))))
  256.     {
  257.         _tprintf(TEXT("Memory allocation error"));
  258.         return NULL;
  259.     }
  260.     
  261.     
  262.     for (nIdx = 0; nIdx < nHeight; nIdx++)
  263.         pbRetValue[nIdx] = pbBuffer + (nIdx * nWidthBytes);
  264.  
  265.     return pbRetValue;
  266. }
  267.  
  268.  
  269. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  270. /* Procedure    :   void ShutDown(void)                                 */
  271. /* Desc.        :   This procedure send a message to the server that it */
  272. /*                  can stop listening for remote procedure calls       */
  273. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  274. void ShutDown(void)
  275. {
  276.     RPC_STATUS nStatus;
  277.  
  278.     /* Tell the server to stop listening for remote procedure calls */
  279.     _tprintf(TEXT("Shutting down the server\n"));
  280.     nStatus = RpcMgmtStopServerListening(NULL);
  281.     EXIT_IF_FAIL(nStatus, "RpcMgmtStopServerListening");
  282. }
  283.  
  284.     
  285.  
  286.