home *** CD-ROM | disk | FTP | other *** search
- /*
- ** WEBCAM
- **
- ** HTTP Wrapper for the Video for Windows Driver
- **
- ** Confidential Property of Tod Sambar
- ** (c) Copyright Tod Sambar 1999
- ** All rights reserved.
- **
- **
- ** Public Functions:
- **
- ** webcam_snapshot
- **
- **
- ** History:
- ** Chg# Date Description Resp
- ** ---- ------- ------------------------------------------------------- ----
- ** 26JUL99 Created sambar
- **
- ** Notes:
- ** Built using release 6b of the Independent JPEG Group's JPEG software
- */
-
- #include <windows.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <webcam.h>
-
- static const char * const cdjpeg_message_table[] = {
- #include "cderror.h"
- NULL
- };
-
-
- /*
- ** WebCam Parameters
- */
- static SA_RPCPARAM webcamp [] =
- {
- { "outfile", 1, "WebCam output JPEG file." },
- { "height", 0, "Snapshot image height." },
- { "width", 0, "Snapshot image width." },
- { "quality", 0, "Quality of JPEG compression (0 - 100)." },
- { "vfwdriver", 0, "VFW driver to use (default is 0)." }
- };
-
- /*
- ** WebCam Defines
- */
- #define WEBCAM_VFW_DRIVER 0
- #define WEBCAM_JPEG_QUALITY 100
- #define WEBCAM_BMP_FILE "capframe.bmp"
-
- /*
- ** WEBCAM_INIT
- **
- ** Initialize the WebCAM Interfaces for use by the
- ** Sambar Server plugins.
- **
- **
- ** Parameters:
- ** sactx Sambar Server context
- **
- ** Returns:
- ** SA_SUCCEED | SA_FAIL
- */
- SA_RETCODE SA_PUBLIC
- webcam_init(sactx)
- SA_CTX *sactx;
- {
- /* Register the WebCAM RPC with the server */
- if (sa_cmd_init(sactx, "webcam_snapshot", webcamp,
- sizeof(webcamp) / sizeof(SA_RPCPARAM), SA_AUTHORIZATION_ADMIN,
- "Sambar Server VFW WebCam snapshot utility.",
- webcam_snapshot) != SA_SUCCEED)
- {
- sa_log2(sactx, SA_LOG_ERROR,
- "Unable to initialize WebCam Snapshot RPC");
- return (SA_FAIL);
- }
-
- sa_log2(sactx, SA_LOG_TRACE, "WebCam Snapshot Initialized");
-
- return (SA_SUCCEED);
- }
-
- /*
- ** WEBCAM_SNAPSHOT
- **
- ** Take a snapshot from the Video for Windows compatible camera and
- ** save the JPEG image.
- **
- ** Parameters:
- ** sactx Sambar Server context
- ** saconn Sambar Server connection
- ** saparams RPC Parameters
- ** infop Error parameters
- **
- ** Returns:
- ** SA_SUCCEED | SA_FAIL
- **
- ** Notes:
- ** Some of the libraries used by this RPC may result in a Server
- ** if an error is experienced. The JPEG library, in particular,
- ** calls exit() rather than gracefully cleaning up errors.
- */
- SA_RETCODE SA_PUBLIC
- webcam_snapshot(sactx, saconn, saparams, infop)
- SA_CTX *sactx;
- SA_CONN *saconn;
- SA_PARAMS *saparams;
- SA_INT *infop;
- {
- int width;
- int height;
- int quality;
- int vfwdriver;
- SA_INT datalen;
- SA_CHAR *data;
- HWND capwin;
- CAPSTATUS capstatus;
- CAPDRIVERCAPS caps;
- struct jpeg_compress_struct cinfo;
- struct jpeg_error_mgr jerr;
- cjpeg_source_ptr src_mgr;
- FILE *infile;
- FILE *outfile;
- JDIMENSION num_scanlines;
- SA_CHAR buffer[256];
-
- /* Initialization */
- width = 0;
- height = 0;
- vfwdriver = WEBCAM_VFW_DRIVER;
- quality = WEBCAM_JPEG_QUALITY;
-
- if ((sa_param(sactx, saparams, "vfwdriver", &data, &datalen) == SA_SUCCEED)
- && (datalen < 12))
- {
- vfwdriver = atoi(data);
- }
-
- if ((sa_param(sactx, saparams, "quality", &data, &datalen) == SA_SUCCEED)
- && (datalen < 12))
- {
- quality = atoi(data);
- }
-
- if ((sa_param(sactx, saparams, "width", &data, &datalen) == SA_SUCCEED)
- && (datalen < 12))
- {
- width = atoi(data);
- }
-
- if ((sa_param(sactx, saparams, "height", &data, &datalen) == SA_SUCCEED)
- && (datalen < 12))
- {
- height = atoi(data);
- }
-
- if ((sa_param(sactx, saparams, "outfile", &data, &datalen) != SA_SUCCEED)
- || (datalen > 255))
- {
- *infop = SA_E_INVALIDDATA;
- sa_log2(sactx, SA_LOG_WARN,
- "webcam_snapshot(): Expected parameter 'outfile'!");
- return (SA_FAIL);
- }
-
-
- /*
- ** Create the capture window
- */
- capwin = capCreateCaptureWindow("Video Capture Window",
- WS_CHILD, 0,0, 0,0, GetDesktopWindow(), 0);
- if (capwin == NULL)
- {
- sa_log2(sactx, SA_LOG_ERROR,
- "webcam_snapshot(): Can't create capture window.");
- return (SA_FAIL);
- }
-
- /* Connect the capture window to the driver */
- if (!capDriverConnect(capwin, vfwdriver))
- {
- sprintf(buffer,
- "webcam_snapshot(): Can't connect to capture driver %d",
- vfwdriver);
- sa_log2(sactx, SA_LOG_ERROR, buffer);
- return (SA_FAIL);
- }
-
- /*
- ** Display the catpure driver name
- **
- ** capGetDriverDescription(index, buffer, sizeof(buffer), NULL, 0);
- ** fprintf(stdout, "Using capture driver: %s\n", buffer);
- */
-
- /* Get the capabilities of the capture driver */
- capDriverGetCaps(capwin, &caps, sizeof(caps));
-
- /* Get the capture window attributes .. width and height */
- capGetStatus(capwin, &capstatus, sizeof(capstatus));
-
- /* Use the default width and height if none is provided. */
- if ((width == 0) || (height == 0))
- {
- width = capstatus.uiImageWidth;
- height = capstatus.uiImageHeight;
- }
-
- /* Resize the capture window to the capture sizes */
- SetWindowPos(capwin, NULL, 0, 0, width, height, SWP_NOMOVE|SWP_NOZORDER);
-
- /* Get a video frame */
- capGrabFrameNoStop(capwin);
- capFileSaveDIB(capwin, (LPCTSTR)WEBCAM_BMP_FILE);
- capDriverDisconnect(capwin);
-
- /*
- ** Initialize the JPEG compression object with default error
- ** handling.
- */
- cinfo.err = jpeg_std_error(&jerr);
- jpeg_create_compress(&cinfo);
-
- /* Add application-specific error messages */
- jerr.addon_message_table = cdjpeg_message_table;
- jerr.first_addon_message = JMSG_FIRSTADDONCODE;
- jerr.last_addon_message = JMSG_LASTADDONCODE;
-
- /*
- ** Initialize JPEG parameters.
- ** Much of this may be overridden later.
- ** In particular, we don't yet know the input file's color space,
- ** but we need to provide some value for jpeg_set_defaults() to work.
- */
- cinfo.in_color_space = JCS_RGB;
- jpeg_set_defaults(&cinfo);
-
- /* Open the input file. */
- if ((infile = fopen(WEBCAM_BMP_FILE, READ_BINARY)) == NULL)
- {
- sprintf(buffer, "webcam_snapshot(): Can't open %s", WEBCAM_BMP_FILE);
- sa_log2(sactx, SA_LOG_ERROR, buffer);
- jpeg_destroy_compress(&cinfo);
- return (SA_FAIL);
- }
-
- /* FIX THIS Sambar - build path to jpeg file relative to homedir */
-
- /* Open the output file. */
- if ((outfile = fopen(data, WRITE_BINARY)) == NULL)
- {
- sprintf(buffer, "webcam_snapshot(): Can't open %s", data);
- sa_log2(sactx, SA_LOG_ERROR, buffer);
- jpeg_destroy_compress(&cinfo);
- return (SA_FAIL);
- }
-
- /* Figure out the input file format, and set up to read it. */
- src_mgr = jinit_read_bmp(&cinfo);
- src_mgr->input_file = infile;
-
- /* Read the input file header to obtain file size & colorspace. */
- (*src_mgr->start_input) (&cinfo, src_mgr);
-
- /*
- ** Now that we know input colorspace, fix colorspace-dependent defaults
- */
- jpeg_default_colorspace(&cinfo);
-
- /* Adjust the compression density */
- if (quality < 0)
- quality = 0;
- else if (quality > 100)
- quality = 100;
-
- jpeg_set_quality(&cinfo, quality, TRUE);
-
- /* Specify data destination for compression */
- jpeg_stdio_dest(&cinfo, outfile);
-
- /* Start compressor */
- jpeg_start_compress(&cinfo, TRUE);
-
- /* Process data */
- while (cinfo.next_scanline < cinfo.image_height)
- {
- num_scanlines = (*src_mgr->get_pixel_rows) (&cinfo, src_mgr);
- (void)jpeg_write_scanlines(&cinfo, src_mgr->buffer,
- num_scanlines);
- }
-
- /* Finish compression and release memory */
- (*src_mgr->finish_input) (&cinfo, src_mgr);
- jpeg_finish_compress(&cinfo);
- jpeg_destroy_compress(&cinfo);
-
- fclose(infile);
- fclose(outfile);
-
- return (SA_SUCCEED);
- }
-