home *** CD-ROM | disk | FTP | other *** search
- /*****
- *
- * VideoUtil.c
- *
- * This is a support file for "Grant's CGI Framework".
- * Please see the license agreement that accompanies the distribution package
- * for licensing details.
- *
- * Copyright ©1996 by Grant Neufeld
- * grant@acm.com
- * http://arpp.carleton.ca/cgi/framework/
- *
- *****/
-
- #include "MemoryUtil.h"
-
- #include "VideoUtil.h"
-
-
- /*** FUNCTIONS ***/
-
- /* Tries to grab the current frame from a QuickCam (if one is installed)
- and will save that image as a JPEG file in the file specified by theFileSpec.
-
- WARNING: This function has not been seriously tested and is probably not very
- robust. Please exercise caution in using it.
-
- digitizerDepth specifies the bit-depth of the image. I recommend you use 32. */
- p_export OSErr
- SaveJPEGFromQuickCam ( FSSpec theFileSpec, short digitizerDepth )
- {
- OSErr theErr;
- PicHandle thePict;
- ComponentDescription theQuickCamDesc;
- Component theQuickCam;
- ComponentInstance theQuickCamInstance;
- Rect maxSrcRect;
- CGrafPtr theWorld;
- CTabHandle cTable;
- PixMapHandle thePMH;
- short videoInputSource;
- GWorldPtr origGWorld;
- GDHandle origGDevice;
- long imageDataSize;
- SInt16 theRefNum;
-
- long maxCompressedSize;
- ImageDescriptionHandle compressedImageDesc;
- Ptr compressedImageData;
-
- thePict = (PicHandle)NewHandle( 0 );
- if ( !thePict || MemError( ) )
- return nil;
-
- //look for a color QuickCam
- theQuickCamDesc.componentType = sgVideoDigitizerType;
- theQuickCamDesc.componentSubType = 'CQCm';
- theQuickCamDesc.componentManufacturer = 'Ctx7';
- theQuickCamDesc.componentFlags = 0;
- theQuickCamDesc.componentFlagsMask = 0;
-
- theQuickCam = FindNextComponent( 0, &theQuickCamDesc );
- if ( !theQuickCam ) //look for the B&W
- {
- theQuickCamDesc.componentType = sgVideoDigitizerType;
- theQuickCamDesc.componentSubType = 'CtxV';
- theQuickCamDesc.componentManufacturer = 'Ctx6';
- theQuickCamDesc.componentFlags = 0;
- theQuickCamDesc.componentFlagsMask = 0;
- }
- if ( !theQuickCam )
- return nil;
-
- theQuickCamInstance = OpenComponent( theQuickCam );
- if ( !theQuickCamInstance )
- return nil;
-
- theErr = VDGetInput( theQuickCamInstance, &videoInputSource );
- if ( theErr )
- return nil;
-
- theErr = VDGetMaxSrcRect( theQuickCamInstance, videoInputSource, &maxSrcRect );
- if ( theErr )
- return nil;
-
- theErr = VDSetDigitizerRect( theQuickCamInstance, &maxSrcRect );
- if ( theErr )
- return nil;
-
- cTable = digitizerDepth != 32 && digitizerDepth != 16 ? GetCTable( digitizerDepth ) : nil;
- theErr = NewGWorld( &theWorld, digitizerDepth, &maxSrcRect, cTable, nil, keepLocal );
- if ( cTable )
- DisposeCTable( cTable );
- if ( theErr )
- return nil;
-
- thePMH = GetGWorldPixMap( theWorld );
- LockPixels( thePMH );
-
- theErr = VDSetPlayThruDestination( theQuickCamInstance, thePMH, &maxSrcRect, nil, nil );
- if ( theErr )
- return nil;
-
- theErr = VDGrabOneFrame( theQuickCamInstance );
- if ( theErr )
- return nil;
-
- GetGWorld( &origGWorld, &origGDevice );
- SetGWorld( theWorld, nil); //get the pictures to save at the proper coordinates
-
- // thePict = OpenPicture( &maxSrcRect );
- // HLock( (Handle)thePMH );
- // CopyBits( (BitMapPtr)*thePMH, (BitMapPtr)*thePMH, &maxSrcRect, &maxSrcRect, srcCopy, nil );
- // HUnlock( (Handle)thePMH );
- // ClosePicture( );
-
- //•••••••••••••••••••••••••••••••••••••
-
- theErr = GetMaxCompressionSize ( thePMH, &maxSrcRect, 32, codecMinQuality, 'jpeg', anyCodec, &maxCompressedSize );
- if ( theErr == noErr )
- {
- compressedImageData = MemoryNewPtr ( maxCompressedSize, &theErr );
- if ( compressedImageData != NULL )
- {
- compressedImageDesc = (ImageDescriptionHandle) MemoryNewHandle ( sizeof(ImageDescription), &theErr );
- if ( compressedImageDesc != NULL )
- {
- theErr = CompressImage ( thePMH, &maxSrcRect, codecMinQuality, 'jpeg', compressedImageDesc, compressedImageData );
-
- if ( theErr == noErr )
- {
- theErr = FSpDelete ( &theFileSpec );
- theErr = FSpCreate ( &theFileSpec, 'JVWR', 'JPEG', smSystemScript );
- }
-
- if ( theErr == noErr )
- {
- theErr = FSpOpenDF ( &theFileSpec, fsWrPerm, &theRefNum );
- if ( theErr == noErr )
- {
- imageDataSize = (*compressedImageDesc)->dataSize;
- theErr = FSWrite ( theRefNum, &imageDataSize, compressedImageData );
-
- FSClose ( theRefNum );
- }
- }
- }
- }
- }
-
- //clean up
- DisposeHandle ( (Handle)compressedImageDesc );
- DisposePtr ( compressedImageData );
-
-
- //•••••••••••
- if ( theWorld )
- DisposeGWorld( theWorld );
-
- SetGWorld( origGWorld, origGDevice );
-
- return theErr;
- } /* SaveJPEGFromQuickCam */
-
-
- /*** EOF ***/
-