home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World 2000 September
/
PCWorld_2000-09_cd.bin
/
Komunik
/
sambar
/
_setup.1
/
webcam.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-06-05
|
8KB
|
304 lines
/*
** 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_log(sactx, "Unable to initialize WebCam Snapshot RPC");
return (SA_FAIL);
}
sa_log(sactx, "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_log(sactx, "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_log(sactx, "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_log(sactx, 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_log(sactx, 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_log(sactx, 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);
}