home *** CD-ROM | disk | FTP | other *** search
/ PC World 2000 September / PCWorld_2000-09_cd.bin / Komunik / sambar / _setup.1 / webcam.c < prev    next >
C/C++ Source or Header  |  2000-06-05  |  8KB  |  304 lines

  1. /*
  2. ** WEBCAM
  3. **
  4. **      HTTP Wrapper for the Video for Windows Driver
  5. **
  6. **        Confidential Property of Tod Sambar
  7. **        (c) Copyright Tod Sambar 1999
  8. **        All rights reserved.
  9. **
  10. **
  11. ** Public Functions:
  12. **
  13. **        webcam_snapshot
  14. **
  15. **
  16. ** History:
  17. ** Chg#    Date    Description                                                Resp
  18. ** ----    -------    -------------------------------------------------------    ----
  19. **         26JUL99    Created                                                    sambar
  20. **
  21. ** Notes:
  22. ** Built using release 6b of the Independent JPEG Group's JPEG software
  23. */
  24.  
  25. #include    <windows.h>
  26. #include    <stdio.h>
  27. #include    <stdlib.h>
  28. #include    <webcam.h>
  29.  
  30. static const char * const cdjpeg_message_table[] = {
  31.     #include "cderror.h"
  32.     NULL
  33. };
  34.  
  35.  
  36. /*
  37. ** WebCam Parameters
  38. */
  39. static SA_RPCPARAM    webcamp [] =
  40. {
  41.     { "outfile",     1,    "WebCam output JPEG file." },
  42.     { "height",     0,    "Snapshot image height." },
  43.     { "width",         0,    "Snapshot image width." },
  44.     { "quality",    0,    "Quality of JPEG compression (0 - 100)." },
  45.     { "vfwdriver",     0,    "VFW driver to use (default is 0)." }
  46. };
  47.  
  48. /*
  49. ** WebCam Defines
  50. */
  51. #define WEBCAM_VFW_DRIVER        0
  52. #define WEBCAM_JPEG_QUALITY        100
  53. #define WEBCAM_BMP_FILE            "capframe.bmp"
  54.  
  55. /*
  56. **  WEBCAM_INIT
  57. **
  58. **    Initialize the WebCAM Interfaces for use by the 
  59. **    Sambar Server plugins.
  60. **
  61. **
  62. **  Parameters:
  63. **    sactx        Sambar Server context
  64. **
  65. **  Returns:
  66. **    SA_SUCCEED | SA_FAIL
  67. */
  68. SA_RETCODE SA_PUBLIC
  69. webcam_init(sactx)
  70. SA_CTX        *sactx;
  71. {
  72.     /* Register the WebCAM RPC with the server                            */
  73.     if (sa_cmd_init(sactx, "webcam_snapshot", webcamp, 
  74.         sizeof(webcamp) / sizeof(SA_RPCPARAM), SA_AUTHORIZATION_ADMIN,
  75.         "Sambar Server VFW WebCam snapshot utility.",
  76.         webcam_snapshot) != SA_SUCCEED)
  77.     {
  78.         sa_log(sactx, "Unable to initialize WebCam Snapshot RPC");
  79.         return (SA_FAIL);
  80.     }
  81.  
  82.     sa_log(sactx, "WebCam Snapshot Initialized");
  83.  
  84.     return (SA_SUCCEED);
  85. }
  86.  
  87. /*
  88. **  WEBCAM_SNAPSHOT
  89. **
  90. **    Take a snapshot from the Video for Windows compatible camera and
  91. **    save the JPEG image.  
  92. **
  93. **  Parameters:
  94. **    sactx        Sambar Server context
  95. **    saconn        Sambar Server connection
  96. **    saparams    RPC Parameters
  97. **    infop        Error parameters
  98. **
  99. **  Returns:
  100. **    SA_SUCCEED | SA_FAIL
  101. **
  102. **    Notes:
  103. **    Some of the libraries used by this RPC may result in a Server
  104. **    if an error is experienced.  The JPEG library, in particular,
  105. **    calls exit() rather than gracefully cleaning up errors.
  106. */
  107. SA_RETCODE SA_PUBLIC
  108. webcam_snapshot(sactx, saconn, saparams, infop)
  109. SA_CTX        *sactx;
  110. SA_CONN        *saconn;
  111. SA_PARAMS    *saparams;
  112. SA_INT        *infop;
  113. {
  114.     int                            width;
  115.     int                            height;
  116.     int                            quality;
  117.     int                            vfwdriver;
  118.     SA_INT                        datalen;
  119.     SA_CHAR                        *data;
  120.     HWND                        capwin;
  121.     CAPSTATUS                     capstatus;
  122.     CAPDRIVERCAPS                caps;
  123.       struct jpeg_compress_struct    cinfo;
  124.       struct jpeg_error_mgr         jerr;
  125.       cjpeg_source_ptr             src_mgr;
  126.       FILE                         *infile;
  127.       FILE                         *outfile;
  128.       JDIMENSION                     num_scanlines;
  129.     SA_CHAR                        buffer[256];
  130.  
  131.     /* Initialization                                                    */
  132.     width = 0;
  133.     height = 0;
  134.     vfwdriver = WEBCAM_VFW_DRIVER;
  135.     quality = WEBCAM_JPEG_QUALITY;
  136.     
  137.     if ((sa_param(sactx, saparams, "vfwdriver", &data, &datalen) == SA_SUCCEED)
  138.         && (datalen < 12))
  139.     {
  140.         vfwdriver = atoi(data);
  141.     }
  142.     
  143.     if ((sa_param(sactx, saparams, "quality", &data, &datalen) == SA_SUCCEED)
  144.         && (datalen < 12))
  145.     {
  146.         quality = atoi(data);
  147.     }
  148.  
  149.     if ((sa_param(sactx, saparams, "width", &data, &datalen) == SA_SUCCEED)
  150.         && (datalen < 12))
  151.     {
  152.         width = atoi(data);
  153.     }
  154.  
  155.     if ((sa_param(sactx, saparams, "height", &data, &datalen) == SA_SUCCEED)
  156.         && (datalen < 12))
  157.     {
  158.         height = atoi(data);
  159.     }
  160.     
  161.     if ((sa_param(sactx, saparams, "outfile", &data, &datalen) != SA_SUCCEED)
  162.         || (datalen > 255))
  163.     {
  164.         *infop = SA_E_INVALIDDATA;
  165.         sa_log(sactx, "webcam_snapshot(): Expected parameter 'outfile'!");
  166.         return (SA_FAIL);
  167.     }
  168.     
  169.  
  170.     /*
  171.     ** Create the capture window
  172.     */
  173.     capwin = capCreateCaptureWindow("Video Capture Window", 
  174.                 WS_CHILD, 0,0, 0,0, GetDesktopWindow(), 0);
  175.     if (capwin == NULL)
  176.     {
  177.         sa_log(sactx, "webcam_snapshot(): Can't create capture window.");
  178.         return (SA_FAIL);
  179.     }
  180.  
  181.     /* Connect the capture window to the driver                            */
  182.     if (!capDriverConnect(capwin, vfwdriver))
  183.     {
  184.         sprintf(buffer, 
  185.             "webcam_snapshot(): Can't connect to capture driver %d", 
  186.             vfwdriver);
  187.         sa_log(sactx, buffer);
  188.         return (SA_FAIL);
  189.     }
  190.  
  191.     /*
  192.     ** Display the catpure driver name                                     
  193.     **
  194.     ** capGetDriverDescription(index, buffer, sizeof(buffer), NULL, 0);
  195.     ** fprintf(stdout, "Using capture driver: %s\n", buffer);
  196.     */
  197.  
  198.     /* Get the capabilities of the capture driver                        */
  199.     capDriverGetCaps(capwin, &caps, sizeof(caps));
  200.  
  201.     /* Get the capture window attributes .. width and height             */
  202.     capGetStatus(capwin, &capstatus, sizeof(capstatus));
  203.  
  204.     /* Use the default width and height if none is provided.            */
  205.     if ((width == 0) || (height == 0))
  206.     {
  207.         width = capstatus.uiImageWidth;
  208.         height = capstatus.uiImageHeight;
  209.     }
  210.  
  211.     /* Resize the capture window to the capture sizes                     */
  212.     SetWindowPos(capwin, NULL, 0, 0, width, height, SWP_NOMOVE|SWP_NOZORDER);
  213.  
  214.     /* Get a video frame                                                 */
  215.     capGrabFrameNoStop(capwin);
  216.     capFileSaveDIB(capwin, (LPCTSTR)WEBCAM_BMP_FILE);
  217.     capDriverDisconnect(capwin);
  218.  
  219.       /* 
  220.     ** Initialize the JPEG compression object with default error 
  221.     ** handling. 
  222.     */
  223.       cinfo.err = jpeg_std_error(&jerr);
  224.       jpeg_create_compress(&cinfo);
  225.  
  226.     /* Add application-specific error messages                            */
  227.     jerr.addon_message_table = cdjpeg_message_table;
  228.     jerr.first_addon_message = JMSG_FIRSTADDONCODE;
  229.     jerr.last_addon_message = JMSG_LASTADDONCODE;
  230.  
  231.       /*
  232.     ** Initialize JPEG parameters.
  233.        ** Much of this may be overridden later.
  234.        ** In particular, we don't yet know the input file's color space,
  235.        ** but we need to provide some value for jpeg_set_defaults() to work.
  236.        */
  237.       cinfo.in_color_space = JCS_RGB;
  238.     jpeg_set_defaults(&cinfo);
  239.  
  240.     /* Open the input file.                                             */
  241.     if ((infile = fopen(WEBCAM_BMP_FILE, READ_BINARY)) == NULL) 
  242.     {
  243.         sprintf(buffer, "webcam_snapshot(): Can't open %s", WEBCAM_BMP_FILE);
  244.         sa_log(sactx, buffer);
  245.         jpeg_destroy_compress(&cinfo);
  246.         return (SA_FAIL);
  247.     }
  248.  
  249.     /* FIX THIS Sambar - build path to jpeg file relative to homedir    */
  250.  
  251.     /* Open the output file.                                             */
  252.     if ((outfile = fopen(data, WRITE_BINARY)) == NULL) 
  253.     {
  254.         sprintf(buffer, "webcam_snapshot(): Can't open %s", data);
  255.         sa_log(sactx, buffer);
  256.         jpeg_destroy_compress(&cinfo);
  257.         return (SA_FAIL);
  258.     }
  259.  
  260.     /* Figure out the input file format, and set up to read it.         */
  261.     src_mgr = jinit_read_bmp(&cinfo);
  262.     src_mgr->input_file = infile;
  263.  
  264.     /* Read the input file header to obtain file size & colorspace.     */
  265.       (*src_mgr->start_input) (&cinfo, src_mgr);
  266.  
  267.     /* 
  268.     ** Now that we know input colorspace, fix colorspace-dependent defaults
  269.     */
  270.     jpeg_default_colorspace(&cinfo);
  271.  
  272.     /* Adjust the compression density                                     */
  273.     if (quality < 0)
  274.         quality = 0;
  275.     else if (quality > 100)
  276.         quality = 100;
  277.  
  278.     jpeg_set_quality(&cinfo, quality, TRUE);
  279.  
  280.     /* Specify data destination for compression                         */
  281.     jpeg_stdio_dest(&cinfo, outfile);
  282.  
  283.     /* Start compressor                                                 */
  284.     jpeg_start_compress(&cinfo, TRUE);
  285.  
  286.     /* Process data                                                     */
  287.     while (cinfo.next_scanline < cinfo.image_height) 
  288.     {
  289.         num_scanlines = (*src_mgr->get_pixel_rows) (&cinfo, src_mgr);
  290.         (void)jpeg_write_scanlines(&cinfo, src_mgr->buffer, 
  291.             num_scanlines);
  292.     }
  293.  
  294.     /* Finish compression and release memory                             */
  295.     (*src_mgr->finish_input) (&cinfo, src_mgr);
  296.     jpeg_finish_compress(&cinfo);
  297.     jpeg_destroy_compress(&cinfo);
  298.  
  299.     fclose(infile);
  300.     fclose(outfile);
  301.  
  302.     return (SA_SUCCEED);
  303. }
  304.