/****************************************************************************** ** File Name : $RCSfile: vpx.c $ ** Short Description : Extension VideoPort Professional toolkit ** Original Project : VideoPort Professional, MS801/MS802 ** Compiler, Version : Borland C++ 3.1,4.0,4.52, Visual C++ 1.0,1.51, ** Watcom C++ 9.5, 10.0 ** Compiler Options : Optimize for speed ** Libraries Used : none ** Original Author : Roar Lauritzsen ** Created (date) : 1995/01/16 ** Last modified by : $Author: Roar_Lauritzsen.NO.MRT $ ** Last modified (date): $Date: 1996/11/27 16:06:28 $ ** Current revision : $Revision: 1.25 $ ($Name: $) ******************************************************************************/ #include #include "vpx.h" #ifdef __WIN32__ #include #define EXPORT __stdcall #define VPP_huge #else #define EXPORT VPP_far _pascal _export #define VPP_huge huge #endif /* This macro checks the return value of a VPP function and returns if error */ #define check(a) { VPP_Errno _e; if ((_e=(a)) != VPP_success) return _e; } HPALETTE VPX_palette = NULL; /****************************************************************************** ** Function name : VPX_defaultConfig ** Description : Fills a MRT Imaging Card configuration structure with ** default values. It can be used to ensure that the ** initial values of the configuration are valid. ** Parameters : config = this parameter contains the configuration of ** the MRT Imaging Card to be filled in. ** Return value : Errno = VPP_success, VPP_badPointer or any error from ** VPP_getLimits. ******************************************************************************/ VPP_Errno EXPORT VPX_defaultConfig (VPX_Config VPP_far *config) { VPP_LimitData limitData; if (config == NULL) return VPP_badPointer; config->videoStandard = VPP_NTSC; config->signalType = VPP_composite; config->inputChannel = VPP_DEFAULT_CHANNEL; config->brightness = VPP_DEFAULT_BRIGHTNESS; config->contrast = VPP_DEFAULT_CONTRAST; config->saturation = VPP_DEFAULT_SATURATION; config->hue = VPP_DEFAULT_HUE; config->gamma = VPP_DEFAULT_GAMMA; config->outputFormat = VPP_BGR24; config->extTrigSnap = VPP_false; config->flashSnap = VPP_false; config->extTrigEnable = VPP_false; config->flashEnable = VPP_false; config->mono4Enable = VPP_true; config->monoEnable = VPP_true; config->RGB8Enable = VPP_true; config->BGR24Enable = VPP_true; #ifdef __WIN32__ config->RGB15Enable = VPP_true; config->RGB16Enable = VPP_true; config->BGR032Enable = VPP_true; #endif check(VPP_getLimits(VPP_PAL, &limitData)); config->snapDataPAL.xOffset = 0; config->snapDataPAL.yOffset = 0; config->snapDataPAL.xActive = limitData.xActiveMax; config->snapDataPAL.yActive = limitData.yActiveMax; #ifndef VPP_NO_STRETCH_IMAGE config->snapDataPAL.xPixels = limitData.xActiveMax; config->snapDataPAL.yPixels = limitData.yActiveMax; #else config->snapDataPAL.xPixels = limitData.xPixelsMax; config->snapDataPAL.yPixels = limitData.yPixelsMax; #endif config->snapDataPAL.monochrome = VPP_false; config->snapDataPAL.interlaced = VPP_true; check(VPP_getLimits(VPP_NTSC, &limitData)); config->snapDataNTSC.xOffset = 0; config->snapDataNTSC.yOffset = 0; config->snapDataNTSC.xActive = limitData.xActiveMax; config->snapDataNTSC.yActive = limitData.yActiveMax; #ifndef VPP_NO_STRETCH_IMAGE config->snapDataNTSC.xPixels = limitData.xActiveMax; config->snapDataNTSC.yPixels = limitData.yActiveMax; #else config->snapDataNTSC.xPixels = limitData.xPixelsMax; config->snapDataNTSC.yPixels = limitData.yPixelsMax; #endif config->snapDataNTSC.monochrome = VPP_false; config->snapDataNTSC.interlaced = VPP_true; return VPP_success; } /****************************************************************************** ** Function name : VPX_prepare ** Description : This function prepares the MRT Imaging Card for using ** a specific MRT Imaging Card configuration. ** The function calls VPP_testSignal, VPP_videoConfig, ** VPP_setBrightness, VPP_setContrast, VPP_setSaturation, ** and VPP_setHue to configure the card, and then it calls ** VPP_getLimits and does a thourough check of all the ** values of the configuration to ensure that the ** configuration is valid. Any values that are out-of- ** bounds are changed to the nearest legal value. ** Parameters : config = this parameter contains the configuration of ** the MRT Imaging Card to be used. ** forceConfig = flag to ensure that the configuration is ** written to the card. If this value is VPP_false, the ** function will only write configuration details that ** are different from the last call to this function. ** This value should always be VPP_true at the start of ** a program. ** Return value : Errno = VPP_success, VPP_badPointer or any error from ** any of the called VPP-functions. ******************************************************************************/ VPP_Errno EXPORT VPX_prepare (VPX_Config VPP_far *config, VPP_Bool forceConfig) { static VPX_Config prevConfig; static VPP_Bool virgin = VPP_true; VPP_SnapData VPP_far *snapData; VPP_LimitData limitData; if (config == NULL) return VPP_badPointer; forceConfig = (forceConfig || virgin); check(VPP_testSignal(&config->videoStandard)); if (config->inputChannel > 1) config->inputChannel = VPP_DEFAULT_CHANNEL; if (config->signalType != VPP_composite && config->signalType != VPP_Svideo && config->signalType != VPP_monochrome) config->signalType = VPP_composite; if (config->inputChannel < 0) config->inputChannel = 0; if (config->inputChannel > 1) config->inputChannel = 1; if (forceConfig || config->inputChannel != prevConfig.inputChannel || config->signalType != prevConfig.signalType || config->videoStandard != prevConfig.videoStandard) { check(VPP_videoConfig((VPP_Byte)config->inputChannel, config->signalType, &config->videoStandard)); } if (config->brightness < VPP_MIN_BRIGHTNESS) config->brightness = VPP_MIN_BRIGHTNESS; if (config->brightness > VPP_MAX_BRIGHTNESS) config->brightness = VPP_MAX_BRIGHTNESS; if (forceConfig || config->brightness != prevConfig.brightness) check(VPP_setBrightness((VPP_Char)config->brightness)); if (config->contrast < VPP_MIN_CONTRAST) config->contrast = VPP_MIN_CONTRAST; if (config->contrast > VPP_MAX_CONTRAST) config->contrast = VPP_MAX_CONTRAST; if (forceConfig || config->contrast != prevConfig.contrast) check(VPP_setContrast((VPP_Char)config->contrast)); if (config->saturation < VPP_MIN_SATURATION) config->saturation = VPP_MIN_SATURATION; if (config->saturation > VPP_MAX_SATURATION) config->saturation = VPP_MAX_SATURATION; if (forceConfig || config->saturation != prevConfig.saturation) check(VPP_setSaturation((VPP_Char)config->saturation)); if (config->hue < VPP_MIN_HUE) config->hue = VPP_MIN_HUE; if (config->hue > VPP_MAX_HUE) config->hue = VPP_MAX_HUE; if (forceConfig || config->hue != prevConfig.hue) check(VPP_setHue((VPP_Char)config->hue)); if (config->gamma <= 0) config->gamma = VPP_DEFAULT_GAMMA; if (forceConfig || config->gamma != prevConfig.gamma) check(VPP_setGamma(config->gamma)); switch (config->outputFormat) { case VPP_mono4: case VPP_mono: case VPP_RGB8: case VPP_BGR24: #ifdef __WIN32__ case VPP_RGB15: case VPP_RGB16: case VPP_BGR032: #endif break; // Mapping all other color modes to be true color. // None of these modes are actually allowed. default: config->outputFormat = VPP_BGR24; break; } if (config->outputFormat == VPP_mono4 && !config->mono4Enable) { if (config->monoEnable) config->outputFormat = VPP_mono; else if (config->BGR24Enable) config->outputFormat = VPP_BGR24; #ifdef __WIN32__ else if (config->RGB16Enable) config->outputFormat = VPP_RGB16; else if (config->RGB15Enable) config->outputFormat = VPP_RGB15; else if (config->BGR032Enable) config->outputFormat = VPP_BGR032; #endif else if (config->RGB8Enable) config->outputFormat = VPP_RGB8; else // At least one outputFormat must be enabled { config->BGR24Enable = VPP_true; config->outputFormat = VPP_BGR24; } } if (config->outputFormat == VPP_mono && !config->monoEnable) { if (config->mono4Enable) config->outputFormat = VPP_mono4; else if (config->BGR24Enable) config->outputFormat = VPP_BGR24; #ifdef __WIN32__ else if (config->RGB16Enable) config->outputFormat = VPP_RGB16; else if (config->RGB15Enable) config->outputFormat = VPP_RGB15; else if (config->BGR032Enable) config->outputFormat = VPP_BGR032; #endif else if (config->RGB8Enable) config->outputFormat = VPP_RGB8; else // At least one outputFormat must be enabled { config->BGR24Enable = VPP_true; config->outputFormat = VPP_BGR24; } } if (config->outputFormat == VPP_RGB8 && !config->RGB8Enable) { if (config->BGR24Enable) config->outputFormat = VPP_BGR24; #ifdef __WIN32__ else if (config->RGB16Enable) config->outputFormat = VPP_RGB16; else if (config->RGB15Enable) config->outputFormat = VPP_RGB15; else if (config->BGR032Enable) config->outputFormat = VPP_BGR032; #endif else if (config->monoEnable) config->outputFormat = VPP_mono; else if (config->mono4Enable) config->outputFormat = VPP_mono4; else // At least one outputFormat must be enabled { config->BGR24Enable = VPP_true; config->outputFormat = VPP_BGR24; } } if (config->outputFormat == VPP_BGR24 && !config->BGR24Enable) { #ifdef __WIN32__ if (config->BGR032Enable) config->outputFormat = VPP_BGR032; else if (config->RGB16Enable) config->outputFormat = VPP_RGB16; else if (config->RGB15Enable) config->outputFormat = VPP_RGB15; else #endif if (config->RGB8Enable) config->outputFormat = VPP_RGB8; else if (config->monoEnable) config->outputFormat = VPP_mono; else if (config->mono4Enable) config->outputFormat = VPP_mono4; else // At least one outputFormat must be enabled { config->BGR24Enable = VPP_true; config->outputFormat = VPP_BGR24; } } #ifdef __WIN32__ if (config->outputFormat == VPP_RGB15 && !config->RGB16Enable) { if (config->RGB16Enable) config->outputFormat = VPP_RGB16; else if (config->BGR24Enable) config->outputFormat = VPP_BGR24; else if (config->BGR032Enable) config->outputFormat = VPP_BGR032; else if (config->RGB8Enable) config->outputFormat = VPP_RGB8; else if (config->monoEnable) config->outputFormat = VPP_mono; else if (config->mono4Enable) config->outputFormat = VPP_mono4; else // At least one outputFormat must be enabled { config->BGR24Enable = VPP_true; config->outputFormat = VPP_BGR24; } } if (config->outputFormat == VPP_RGB16 && !config->RGB16Enable) { if (config->RGB15Enable) config->outputFormat = VPP_RGB15; else if (config->BGR24Enable) config->outputFormat = VPP_BGR24; else if (config->BGR032Enable) config->outputFormat = VPP_BGR032; else if (config->RGB8Enable) config->outputFormat = VPP_RGB8; else if (config->monoEnable) config->outputFormat = VPP_mono; else if (config->mono4Enable) config->outputFormat = VPP_mono4; else // At least one outputFormat must be enabled { config->BGR24Enable = VPP_true; config->outputFormat = VPP_BGR24; } } if (config->outputFormat == VPP_BGR032 && !config->BGR032Enable) { if (config->BGR24Enable) config->outputFormat = VPP_BGR24; else if (config->RGB16Enable) config->outputFormat = VPP_RGB16; else if (config->RGB15Enable) config->outputFormat = VPP_RGB15; else if (config->RGB8Enable) config->outputFormat = VPP_RGB8; else if (config->monoEnable) config->outputFormat = VPP_mono; else if (config->mono4Enable) config->outputFormat = VPP_mono4; else // At least one outputFormat must be enabled { config->BGR24Enable = VPP_true; config->outputFormat = VPP_BGR24; } } #endif config->snapDataNTSC.monochrome = config->snapDataPAL.monochrome = (config->outputFormat == VPP_mono || config->outputFormat == VPP_mono4); config->extTrigSnap = config->extTrigSnap && config->extTrigEnable; config->flashSnap = config->flashSnap && config->flashEnable; if (config->extTrigSnap && config->flashSnap) // Mutually exclusive config->flashSnap = VPP_false; check(VPP_getLimits(config->videoStandard, &limitData)); snapData = (config->videoStandard == VPP_PAL ? &config->snapDataPAL : &config->snapDataNTSC); if (snapData->xPixels > limitData.xPixelsMax) snapData->xPixels = limitData.xPixelsMax; if (snapData->xPixels < 10) snapData->xPixels = 10; if (snapData->xOffset > limitData.xActiveMax-10) snapData->xOffset = limitData.xActiveMax-10; if (snapData->xActive+snapData->xOffset > limitData.xActiveMax) snapData->xActive = limitData.xActiveMax-snapData->xOffset; if (snapData->xActive < 10) snapData->xActive = 10; #ifdef VPP_NO_STRETCH_IMAGE if (snapData->xPixels > snapData->xActive) snapData->xPixels = snapData->xActive; #endif /* VPP_STRETCH_IMAGE */ if ((long)snapData->xPixels*limitData.xActiveRatio < (long)snapData->xActive*limitData.xPixelsRatio) snapData->xPixels = (VPP_Word)((long)snapData->xActive* limitData.xPixelsRatio/limitData.xActiveRatio + 1); if (snapData->interlaced == VPP_false) limitData.yActiveMax /= 2; if (snapData->yPixels > limitData.yPixelsMax) snapData->yPixels = limitData.yPixelsMax; if (snapData->yPixels < 10) snapData->yPixels = 10; if (snapData->yOffset > limitData.yActiveMax-10) snapData->yOffset = limitData.yActiveMax-10; if (snapData->yActive+snapData->yOffset > limitData.yActiveMax) snapData->yActive = limitData.yActiveMax-snapData->yOffset; if (snapData->yActive < 10) snapData->yActive = 10; #ifdef VPP_NO_STRETCH_IMAGE if (snapData->yPixels > snapData->yActive) snapData->yPixels = snapData->yActive; #endif /* VPP_STRETCH_IMAGE */ if ((long)snapData->yPixels*limitData.yActiveRatio < (long)snapData->yActive*limitData.yPixelsRatio) snapData->yPixels = (VPP_Word)((long)snapData->yActive* limitData.yPixelsRatio/limitData.yActiveRatio + 1); prevConfig = *config; virgin = VPP_false; return VPP_success; } /****************************************************************************** ** Function name : VPX_snap ** Description : Grab image to framebuffer of Video Port. ** This function uses VPP_prepareSnap, VPP_startSnap and ** VPP_finishSnap to grab the image. VPX_prepare (or ** VPP_videoConfig) must be called before calling this ** function. ** Parameters : config = this parameter contains the configuration of ** the MRT Imaging Card. ** Return value : Errno = VPP_success, VPP_badPointer, or any VPP_Errno ** from VPP_prepareSnap, VPP_startSnap or VPP_finishSnap. ******************************************************************************/ VPP_Errno EXPORT VPX_snap (VPX_Config VPP_far *config) { VPP_SnapData VPP_far *snapData; if (config == NULL) return VPP_badPointer; snapData = (config->videoStandard == VPP_PAL ? &config->snapDataPAL : &config->snapDataNTSC); check(VPP_prepareSnap(snapData)); if (config->extTrigSnap) { check(VPP_extTrigSnap(10200)); /* max 255 frames integration = 10.2 sec */ } else if (config->flashSnap) { check(VPP_flashSnap()); } else { check(VPP_startSnap()); check(VPP_finishSnap()); } return VPP_success; } /****************************************************************************** ** Function name : VPX_draw ** Description : Get image from the framebuffer and draw it in a window. ** This function uses VPX_readoutDIB to read the image and ** VPX_drawDIB to draw the image. ** Parameters : hDC = Handle to the device context. ** config = this parameter contains the configuration of ** the MRT Imaging Card. The config->outputFormat value ** must be one of the following: ** VPP_mono4 : 16 colors monochrome image ** VPP_mono : 256 colors monochrome image ** VPP_RGB8 : 256 color image ** VPP_BGR24 : 16M color image ** all other values will be treated as VPP_BGR24. ** xPos, yPos = Top left position where the image will be ** drawn inside the window. ** xSize, ySize = Width and height to be used when drawing ** the image. If these values differ from ** config->snapDataX.xPixels and .yPixels, the image will ** be stretched. ** NOTE : When an error is returned from this function, the ** VPP_lastErrorFunctionName may not return the correct ** function name. ** Return value : Errno = VPP_success, VPP_badPointer, or any error ** message from VPX_readoutDIB or VPX_drawDIB. ******************************************************************************/ VPP_Errno EXPORT VPX_draw (HDC hDC, VPX_Config VPP_far *config, VPP_Word xPos, VPP_Word yPos, VPP_Word xSize, VPP_Word ySize) { HGLOBAL DIB = NULL; VPP_Errno retValue; DWORD colors; VPP_ReadoutMode prevMode; if (config == NULL) return VPP_badPointer; colors = ((DWORD) 1) << (GetDeviceCaps (hDC,PLANES) * GetDeviceCaps (hDC,BITSPIXEL)); prevMode = config->outputFormat; switch (config->outputFormat) { case VPP_mono4: case VPP_mono: case VPP_RGB8: case VPP_BGR24: #ifdef __WIN32__ case VPP_RGB15: case VPP_RGB16: case VPP_BGR032: #endif break; // Mapping all other color modes to be true color. // None of these modes are actually allowed. default: config->outputFormat = VPP_BGR24; break; } if ((colors <= 256) && (config->outputFormat == VPP_BGR24)) { config->outputFormat = VPP_RGB8; } retValue = VPX_readoutDIB (config, &DIB); config->outputFormat = prevMode; // Restore the outputFormat if (retValue != VPP_success) return retValue; retValue = VPX_drawDIB(hDC,DIB,xPos,yPos,xSize,ySize); GlobalFree (DIB); return retValue; } /****************************************************************************** ** Function name : VPX_drawDIB ** Description : Draw a DIB bitmap in a window. ** Parameters : hDC = Handle to the device context. ** hDIB = Handle to the DIB. This DIB must have been ** created by VPX_readoutDIB or have a compatible format. ** xPos, yPos = Top left position where the image will be ** drawn inside the window. ** xSize, ySize = Width and height to be used when drawing ** the image. If these values differ from ** config->snapDataX.xPixels and .yPixels, the image will ** be stretched. ** NOTE : When an error is returned from this function, the ** VPP_lastErrorFunctionName may not return the correct ** function name. ** Return value : Errno = VPP_success, VPP_badPointer or VPP_outOfMemory. ******************************************************************************/ VPP_Errno EXPORT VPX_drawDIB (HDC hDC, HGLOBAL hDIB, VPP_Word xPos, VPP_Word yPos, VPP_Word xSize, VPP_Word ySize) { BYTE VPP_huge *pDIB; // pointer to bitmap info void VPP_far *data; // pointer to the BID bits. BITMAPINFO VPP_far *pbmi; DWORD headerSize; if (hDIB == NULL) return VPP_badPointer; pDIB = (BYTE VPP_far*) GlobalLock (hDIB) ; if (pDIB == NULL) { // Could not lock the memory. return VPP_outOfMemory; } pbmi = (BITMAPINFO VPP_far*) pDIB; headerSize = sizeof(BITMAPINFOHEADER); #ifdef __WIN32__ if (pbmi->bmiHeader.biCompression == BI_BITFIELDS) headerSize += 3*sizeof(DWORD); #endif if (pbmi->bmiHeader.biBitCount <= 8) headerSize += pbmi->bmiHeader.biClrUsed * sizeof (RGBQUAD); data = pDIB + headerSize; if (VPX_palette != NULL) // No palette is set up, no need to realise it. { SelectPalette (hDC, VPX_palette, FALSE); RealizePalette (hDC); } if ((xSize == VPX_DEFAULT || xSize == pbmi->bmiHeader.biWidth) && (ySize == VPX_DEFAULT || ySize == pbmi->bmiHeader.biHeight)) { // Use bitmaps size to draw on the screen. SetDIBitsToDevice(hDC, xPos, yPos, pbmi->bmiHeader.biWidth, pbmi->bmiHeader.biHeight, 0, 0, 0,pbmi->bmiHeader.biHeight, data, (LPBITMAPINFO) pDIB, DIB_RGB_COLORS); } else { // Setting the right x and y size if only one given as VPX_DEFAULT if (xSize == VPX_DEFAULT) { xSize = (VPP_Word)pbmi->bmiHeader.biWidth; } if (ySize == VPX_DEFAULT) { ySize = (VPP_Word)pbmi->bmiHeader.biHeight; } // Stretch the bitmap to the required size. SetStretchBltMode (hDC, STRETCH_DELETESCANS); StretchDIBits(hDC, xPos, yPos, xSize, ySize, 0, 0, pbmi->bmiHeader.biWidth, pbmi->bmiHeader.biHeight, data, (LPBITMAPINFO)pDIB, DIB_RGB_COLORS, SRCCOPY); } GlobalUnlock (hDIB); return VPP_success; } /****************************************************************************** ** Function name : VPX_readoutDIB ** Description : Read framebuffer and return a DIB. ** This function uses VPP_startReadout and VPP_readLine to ** read the image. ** Parameters : config = this parameter contains the configuration of ** the MRT Imaging Card. The config->outputFormat value ** must be one of the following: ** VPP_mono4 : 16 colors monochrome image ** VPP_mono : 256 colors monochrome image ** VPP_RGB8 : 256 color image ** VPP_BGR24 : 16M color image ** in WIN32 these formats are also allowed: ** VPP_RGB15 : 32k color image ** VPP_RGB16 : 64k color image ** VPP_BGR032 : 32bit color image ** phDIB = pointer to handle to return the DIB in. ** NOTE : When an error is returned from this function, the ** VPP_lastErrorFunctionName may not return the correct ** function name. ** Return value : Errno = VPP_success, VPP_badPointer, ** VPP_parameterOutOfRange, VPP_outOfMemory, or any return ** value from VPP_startReadout and VPP_readLine. ******************************************************************************/ VPP_Errno EXPORT VPX_readoutDIB(VPX_Config VPP_far *config, HGLOBAL VPP_far *phDIB) { HGLOBAL hglb; BYTE VPP_far *linebuf; BYTE VPP_huge *bitmappos; BITMAPINFO VPP_far *pbmi; WORD i; VPP_Word linelength; WORD ncolors; WORD bitsPerPixel; DWORD headerSize; VPP_SnapData VPP_far *snapData; if (config == NULL || phDIB == NULL) return VPP_badPointer; snapData = (config->videoStandard == VPP_PAL ? &config->snapDataPAL : &config->snapDataNTSC); *phDIB = NULL; check(VPP_startReadout(config->outputFormat,0)); switch (config->outputFormat) { case VPP_mono4 : bitsPerPixel = 4; break; case VPP_mono : case VPP_RGB8 : bitsPerPixel = 8; break; case VPP_BGR24 : bitsPerPixel = 24; break; #ifdef __WIN32__ case VPP_RGB15 : case VPP_RGB16 : bitsPerPixel = 16; break; case VPP_BGR032 : bitsPerPixel = 32; break; #endif default: return VPP_parameterOutOfRange; } ncolors = (bitsPerPixel <= 8) ? (1<xPixels*bitsPerPixel+31)/32)*4; headerSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*ncolors; #ifdef __WIN32__ if (config->outputFormat == VPP_RGB16) { headerSize += 3*sizeof(DWORD); /* The following line is probably a bugfix that may have to be removed in the future */ ncolors = 3; } #endif hglb = GlobalAlloc(GMEM_MOVEABLE,(LONG)linelength); if (hglb == NULL || (linebuf = (BYTE VPP_far *)GlobalLock(hglb)) == NULL) { GlobalFree(hglb); #ifndef VPX_NO_MESSAGES MessageBox (NULL, "Can't allocate memory !", "Error", MB_OK); #endif return VPP_outOfMemory; } *phDIB = GlobalAlloc(GMEM_MOVEABLE,headerSize + (LONG)snapData->yPixels * linelength); if (*phDIB == NULL || (pbmi = (BITMAPINFO VPP_far *)GlobalLock(*phDIB)) == NULL) { GlobalUnlock(hglb); GlobalFree(hglb); GlobalFree(*phDIB); #ifndef VPX_NO_MESSAGES MessageBox (NULL, "Can't lock memory !", "Error", MB_OK); #endif return VPP_outOfMemory; } pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); pbmi->bmiHeader.biWidth = snapData->xPixels; pbmi->bmiHeader.biHeight = snapData->yPixels; pbmi->bmiHeader.biPlanes = 1; pbmi->bmiHeader.biBitCount = bitsPerPixel; #ifdef __WIN32__ if (config->outputFormat == VPP_RGB16) pbmi->bmiHeader.biCompression = BI_BITFIELDS; else #endif pbmi->bmiHeader.biCompression = BI_RGB; pbmi->bmiHeader.biSizeImage = (LONG)linelength*snapData->yPixels; pbmi->bmiHeader.biXPelsPerMeter = 0x1711; /* 300 DPI */ pbmi->bmiHeader.biYPelsPerMeter = 0x1711; /* 300 DPI */ pbmi->bmiHeader.biClrUsed = ncolors; pbmi->bmiHeader.biClrImportant = ncolors; switch (config->outputFormat) { case VPP_mono4: for (i=0; i < ncolors; i++) { pbmi->bmiColors[i].rgbBlue = (BYTE)(i*17); pbmi->bmiColors[i].rgbRed = (BYTE)(i*17); pbmi->bmiColors[i].rgbGreen = (BYTE)(i*17); pbmi->bmiColors[i].rgbReserved = 0; } break; case VPP_mono: for (i=0; ibmiColors[i].rgbBlue = (BYTE)i; pbmi->bmiColors[i].rgbRed = (BYTE)i; pbmi->bmiColors[i].rgbGreen = (BYTE)i; pbmi->bmiColors[i].rgbReserved = 0; } break; case VPP_RGB8: for (i=0; ibmiColors[i].rgbBlue = (BYTE)((i&3)*85); pbmi->bmiColors[i].rgbRed = (BYTE)(((i>>5)&7)*73/2); pbmi->bmiColors[i].rgbGreen = (BYTE)(((i>>2)&7)*73/2); pbmi->bmiColors[i].rgbReserved = 0; } break; #ifdef __WIN32__ case VPP_RGB16: *(DWORD*)(&pbmi->bmiColors[0]) = 0xF800; *(DWORD*)(&pbmi->bmiColors[1]) = 0x07E0; *(DWORD*)(&pbmi->bmiColors[2]) = 0x001F; break; #endif default: break; } bitmappos = (BYTE VPP_huge *)pbmi + headerSize + (LONG)(snapData->yPixels-1)*linelength; for (i=0; i < snapData->yPixels; i++) { #ifndef __WIN32__ if (0x10000L-FP_OFF(bitmappos) < (LONG)linelength) { check(VPP_readLine(linebuf,0,snapData->xPixels)); hmemcpy(bitmappos,linebuf,linelength); } else #endif VPP_readLine(bitmappos,0,snapData->xPixels); bitmappos -= linelength; } GlobalUnlock (hglb); GlobalFree (hglb); GlobalUnlock (*phDIB); return VPP_success; } /****************************************************************************** ** Function name : VPX_readoutDIBToClipboard ** Description : Read framebuffer and put it as a DIB on the clipboard. ** This function uses VPX_readoutDIB to read the image, ** and VPX_saveDIBToClipboard to put the image on the ** clipboard. ** Parameters : config = this parameter contains the configuration of ** the MRT Imaging Card. The config->outputFormat value ** must be one of the following: ** VPP_mono4 : 16 colors monochrome image ** VPP_mono : 256 colors monochrome image ** VPP_RGB8 : 256 color image ** VPP_BGR24 : 16M color image ** in WIN32 these formats are also allowed: ** VPP_RGB15 : 32k color image ** VPP_RGB16 : 64k color image ** VPP_BGR032 : 32bit color image ** NOTE : The return value VPP_badPointer is used as a generic ** error value to signal an error in this function. ** The VPP_lastErrorFunctionName may not return the correct ** function name. ** Return value : Errno = VPP_success or any return value ** from VPX_readoutDIB and VPX_saveDIBToClipboard. ******************************************************************************/ VPP_Errno EXPORT VPX_readoutDIBToClipboard(VPX_Config VPP_far *config) { HGLOBAL hDIB; check(VPX_readoutDIB(config,&hDIB)); check(VPX_saveDIBToClipboard(hDIB)); return VPP_success; } /****************************************************************************** ** Function name : VPX_saveDIBToClipboard ** Description : Put the DIB on the clipboard. ** Parameters : hDIB = Handle to DIB which is to be put on the ** clipboard. The DIB must be generated by a VPX function ** to ensure the proper format. ** IMPORTANT! : After the DIB is put on the clipboard, THE DIB MUST NOT ** BE USED OR FREED by the calling application. From then ** on it is the clipboard that owns the DIB and sees to ** that it is freed when necessary. ** NOTE : The return value VPP_badPointer is used as a generic ** error value to signal an error in this function. ** The VPP_lastErrorFunctionName will not return the ** correct function name. ** Return value : Errno = VPP_success or VPP_badPointer ******************************************************************************/ VPP_Errno EXPORT VPX_saveDIBToClipboard(HGLOBAL hDIB) { if (hDIB == NULL) return VPP_badPointer; if (OpenClipboard(0)) { hDIB = SetClipboardData(CF_DIB,hDIB); if (hDIB != NULL && VPX_palette != NULL) { WORD nColors; HANDLE hLogPal; HPALETTE hPalette; LOGPALETTE* logPal; if (GetObject(VPX_palette,sizeof(nColors),&nColors) == sizeof(nColors)) { hLogPal = GlobalAlloc(GMEM_MOVEABLE,sizeof(LOGPALETTE) + (nColors-1)*sizeof(PALETTEENTRY)); if (hLogPal != NULL && (logPal = (LOGPALETTE*)GlobalLock(hLogPal)) != NULL) { logPal->palVersion = 0x300; logPal->palNumEntries = nColors; GetPaletteEntries(VPX_palette, 0, nColors, logPal->palPalEntry); if ((hPalette = CreatePalette(logPal)) != NULL) SetClipboardData(CF_PALETTE,hPalette); GlobalFree(hLogPal); } } } CloseClipboard(); } else hDIB = NULL; if (hDIB == NULL) { #ifndef VPX_NO_MESSAGES MessageBox (NULL, "Can't open Clipboard !", "Error", MB_OK); #endif return VPP_badPointer; } /* NOTE! hDIB must not be used (such as GlobalFree(hDIB)) after it is put on the clipboard */ return VPP_success; } /****************************************************************************** ** Function name : VPX_readoutDIBToFile ** Description : Read framebuffer and save it as a DIB file. ** This function uses VPP_startReadout and VPP_readLine to ** read the image, and does not require as much memory as ** VPX_readoutDIB does. ** Parameters : config = this parameter contains the configuration of ** the MRT Imaging Card. The config->outputFormat value ** must be one of the following: ** VPP_mono4 : 16 colors monochrome image ** VPP_mono : 256 colors monochrome image ** VPP_RGB8 : 256 color image ** VPP_BGR24 : 16M color image ** in WIN32 these formats are also allowed: ** VPP_RGB15 : 32k color image ** VPP_RGB16 : 64k color image ** VPP_BGR032 : 32bit color image ** filename = name of file to save the DIB to. This file ** will be overwritten if it exists. It is the user's ** responsibility that the filename has the proper ** extension (=".BMP") and a valid path. ** NOTE : If an error occurs in this function, ** VPP_lastErrorFunctionName may not return the correct ** function name. ** Return value : Errno = VPP_success, VPP_parameterOutOfRange, ** VPP_badPointer, VPP_fileIOError, VPP_outOfMemory or any ** return value from VPP_startReadout and VPP_readLine. ******************************************************************************/ VPP_Errno EXPORT VPX_readoutDIBToFile(VPX_Config VPP_far *config, char VPP_far *filename) { HGLOBAL hglb; char VPP_far *linebuf; struct { BITMAPFILEHEADER bfh; BITMAPINFOHEADER bih; } fileHeader; RGBQUAD col; HFILE file; OFSTRUCT ofstr; int err; WORD i; VPP_Word linelength; WORD ncolors; WORD bitsPerPixel; VPP_SnapData VPP_far *snapData; if (config == NULL || filename == NULL) return VPP_badPointer; snapData = (config->videoStandard == VPP_PAL ? &config->snapDataPAL : &config->snapDataNTSC); switch (config->outputFormat) { case VPP_mono4 : bitsPerPixel = 4; break; case VPP_mono : case VPP_RGB8 : bitsPerPixel = 8; break; case VPP_BGR24 : bitsPerPixel = 24; break; #ifdef __WIN32__ case VPP_RGB15 : case VPP_RGB16 : bitsPerPixel = 16; break; case VPP_BGR032 : bitsPerPixel = 32; break; #endif default: return VPP_parameterOutOfRange; } ncolors = (bitsPerPixel <= 8) ? (1<xPixels*bitsPerPixel+31)/32)*4; hglb = GlobalAlloc(GMEM_MOVEABLE,(LONG)linelength); if (hglb == NULL) { #ifndef VPX_NO_MESSAGES MessageBox (NULL, "Can't allocate memory !", "Error", MB_OK); #endif return VPP_outOfMemory; } linebuf = (char VPP_far *)GlobalLock(hglb); if (linebuf == NULL) { #ifndef VPX_NO_MESSAGES MessageBox (NULL, "Can't allocate memory !", "Error", MB_OK); #endif return VPP_outOfMemory; } fileHeader.bfh.bfType = 0x4D42; /* 'BM' */ fileHeader.bfh.bfOffBits = sizeof(fileHeader) + sizeof(RGBQUAD)*ncolors; fileHeader.bfh.bfSize = fileHeader.bfh.bfOffBits + (LONG)linelength*snapData->yPixels; fileHeader.bfh.bfReserved1 = 0; fileHeader.bfh.bfReserved2 = 0; fileHeader.bih.biSize = sizeof(BITMAPINFOHEADER); fileHeader.bih.biWidth = snapData->xPixels; fileHeader.bih.biHeight = snapData->yPixels; fileHeader.bih.biPlanes = 1; fileHeader.bih.biBitCount = bitsPerPixel; fileHeader.bih.biSizeImage = (LONG)linelength*snapData->yPixels; fileHeader.bih.biXPelsPerMeter = 0x2E22; /* 300 DPI */ fileHeader.bih.biYPelsPerMeter = 0x2E22; /* 300 DPI */ fileHeader.bih.biClrUsed = ncolors; fileHeader.bih.biClrImportant = ncolors; #ifdef __WIN32__ if (config->outputFormat == VPP_RGB16) { fileHeader.bih.biCompression = BI_BITFIELDS; fileHeader.bfh.bfOffBits += 3*sizeof(DWORD); /* The following line is probably a bugfix that may have to be removed in the future */ fileHeader.bih.biClrUsed = 3; } else #endif fileHeader.bih.biCompression = BI_RGB; file = OpenFile(filename,&ofstr,OF_CREATE|OF_WRITE); err = (file == HFILE_ERROR || _lwrite(file,(char*)&fileHeader,sizeof(fileHeader)) != sizeof(fileHeader)); #ifdef __WIN32__ if (config->outputFormat == VPP_RGB16) { static DWORD bitfields[3] = { 0xF800, 0x07E0, 0x001F }; err = (_lwrite(file,(char*)&bitfields,3*sizeof(DWORD)) != 3*sizeof(DWORD)); } #endif for (i=0; ioutputFormat) { case VPP_mono4: col.rgbBlue = (BYTE)(i*17); col.rgbRed = (BYTE)(i*17); col.rgbGreen = (BYTE)(i*17); col.rgbReserved = 0; break; case VPP_mono: col.rgbBlue = (BYTE)i; col.rgbRed = (BYTE)i; col.rgbGreen = (BYTE)i; col.rgbReserved = 0; break; case VPP_RGB8: col.rgbBlue = (BYTE)((i&3)*85); col.rgbRed = (BYTE)(((i>>5)&7)*73/2); col.rgbGreen = (BYTE)(((i>>2)&7)*73/2); col.rgbReserved = 0; break; default: break; } err = (_lwrite(file,(char*)&col,sizeof(col)) != sizeof(col)); } for (i=0; iyPixels && !err; i++) { check(VPP_startReadout(config->outputFormat,0)); check(VPP_skipLines((VPP_Word)(snapData->yPixels-1-i))); check(VPP_readLine(linebuf,0,snapData->xPixels)); err = (_lwrite(file,linebuf,linelength) != linelength); } if (file != HFILE_ERROR) { _lclose(file); } GlobalUnlock(hglb); GlobalFree(hglb); if (err) { #ifndef VPX_NO_MESSAGES MessageBox (NULL, "An error occurred when writing to file", "Error", MB_OK); #endif return VPP_fileIOError; } return VPP_success; } /****************************************************************************** ** Function name : VPX_saveDIBToFile ** Description : Saves a DIB in a BMP file. ** Parameters : hDIB = Handle to DIB which is to be saved * The DIB must be generated by a VPX function ** to ensure the proper format. ** filename = name of file to save the DIB to. This file ** will be overwritten if it exists. It is the user's ** responsibility that the filename has the proper ** extension (=".BMP") and a valid path. ** NOTE : If an error occurs in this function, ** VPP_lastErrorFunctionName will not return the correct ** function name. ** Return value : Errno = VPP_success, VPP_badPointer or VPP_fileIOError ******************************************************************************/ VPP_Errno EXPORT VPX_saveDIBToFile(HGLOBAL hDIB, char VPP_far *filename) { BITMAPFILEHEADER bfh; BITMAPINFO VPP_far *pbmi; DWORD bytesLeft; BOOL ok; DWORD bytesToWrite; #ifdef __WIN32__ HANDLE file; #else OFSTRUCT ofstr; HFILE file; BYTE VPP_huge *bytePos; #endif if (hDIB == NULL || filename == NULL) return VPP_badPointer; if ((pbmi = (BITMAPINFO VPP_far *)GlobalLock(hDIB)) == NULL) return VPP_outOfMemory; bfh.bfType = 0x4D42; /* 'BM' */ bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); if (pbmi->bmiHeader.biBitCount <= 8) bfh.bfOffBits += pbmi->bmiHeader.biClrUsed*sizeof(RGBQUAD); #ifdef __WIN32__ if (pbmi->bmiHeader.biCompression == BI_BITFIELDS) bfh.bfOffBits += 3*sizeof(DWORD); #endif bfh.bfSize = bfh.bfOffBits + pbmi->bmiHeader.biSizeImage; bfh.bfReserved1 = 0; bfh.bfReserved2 = 0; bytesLeft = bfh.bfSize - sizeof(BITMAPFILEHEADER); #ifdef __WIN32__ ok = ((file = CreateFile(filename,GENERIC_WRITE,0,NULL,CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL)) != INVALID_HANDLE_VALUE); if (ok) { ok = WriteFile(file,&bfh,sizeof(BITMAPFILEHEADER),&bytesToWrite,NULL) && WriteFile(file,pbmi,bytesLeft,&bytesToWrite,NULL); CloseHandle(file); } GlobalUnlock(hDIB); if (!ok) return VPP_fileIOError; #else file = OpenFile(filename,&ofstr,OF_CREATE|OF_WRITE); ok = (file != HFILE_ERROR && _lwrite(file,(char*)&bfh,sizeof(BITMAPFILEHEADER)) == sizeof(BITMAPFILEHEADER)); bytePos = (BYTE VPP_huge *)pbmi; while (ok && bytesLeft > 0) { bytesToWrite = 0x10000L-FP_OFF(bytePos); // Do not wrap segment if (bytesToWrite > 0x8000) bytesToWrite = 0x8000; // Maximum 32768 bytes at a time if (bytesToWrite > bytesLeft) bytesToWrite = bytesLeft; ok = (_lwrite(file,bytePos,(UINT)bytesToWrite) == (UINT)bytesToWrite); bytePos += bytesToWrite; bytesLeft -= bytesToWrite; } GlobalUnlock(hDIB); if (file != HFILE_ERROR) _lclose(file); if (!ok) return VPP_fileIOError; #endif return VPP_success; } /****************************************************************************** ** Function name : VPX_snapAverageDIB ** Description : Snap several images and calculate an image which is the ** average of all the snapped images. ** This function uses VPP_prepareSnap, VPP_startSnap, ** VPP_finishSnap, VPP_startReadout, VPP_readLine and ** VPP_convertYCrCbToBGR24 to calculate the average image. ** A temporary buffer which is about twice as large as the ** resulting image is used during the calculation. ** Parameters : config = this parameter contains the configuration of ** the MRT Imaging Card. The config->outputFormat value ** must be one of the following: ** VPP_mono : 256 colors monochrome image ** VPP_BGR24 : 16M color image ** phDIB = pointer to handle to return the DIB in. ** numAverage = number of images to average ** divideBy = when all the images are added together, each ** pixel is divided by this value. For normal averaging, ** divideBy should be equal to numAverage. To boost the ** brightness of a dark image, divideBy may be less than ** numAverage. ** Return value : Errno = VPP_success, VPP_parameterOutOfRange, ** VPP_badPointer, VPP_outOfMemory, or any return value ** from the used VPP functions. ******************************************************************************/ VPP_Errno EXPORT VPX_snapAverageDIB(VPX_Config VPP_far *config, HGLOBAL VPP_far *phDIB, VPP_Byte numAverage, VPP_Byte divideBy) { HGLOBAL hglb; BITMAPINFO VPP_far *pbmi; BYTE VPP_far *linebuf; BYTE VPP_huge *bitmappos; BYTE VPP_huge *bitmappos2; WORD VPP_huge *pAvg; WORD x,y; WORD linelength; WORD avgLinelength; WORD ncolors; WORD bitsPerPixel; VPP_SnapData VPP_far *snapData; DWORD headerSize; if (config == NULL || phDIB == NULL) return VPP_badPointer; snapData = (config->videoStandard == VPP_PAL ? &config->snapDataPAL : &config->snapDataNTSC); *phDIB = NULL; switch (config->outputFormat) { case VPP_mono : bitsPerPixel = 8; ncolors = 256; break; case VPP_BGR24 : bitsPerPixel = 24; ncolors = 0; break; default: return VPP_parameterOutOfRange; } linelength = ((snapData->xPixels*bitsPerPixel+31)/32)*4; headerSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*ncolors; avgLinelength = ((snapData->xPixels+1)/2)*4; if (config->outputFormat == VPP_BGR24) avgLinelength *= 2; hglb = GlobalAlloc(GMEM_MOVEABLE,(LONG)avgLinelength*2); if (hglb == NULL || (linebuf = (BYTE VPP_far *)GlobalLock(hglb)) == NULL) { GlobalFree(hglb); #ifndef VPX_NO_MESSAGES MessageBox (NULL, "Can't allocate memory !", "Error", MB_OK); #endif return VPP_outOfMemory; } *phDIB = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,headerSize + (LONG)snapData->yPixels * avgLinelength); if (*phDIB == NULL || (pbmi = (BITMAPINFO VPP_far *)GlobalLock(*phDIB)) == NULL) { GlobalUnlock(hglb); GlobalFree(hglb); GlobalFree(*phDIB); #ifndef VPX_NO_MESSAGES MessageBox (NULL, "Can't lock memory !", "Error", MB_OK); #endif return VPP_outOfMemory; } pbmi = (BITMAPINFO VPP_far *)GlobalLock(*phDIB); pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); pbmi->bmiHeader.biWidth = snapData->xPixels; pbmi->bmiHeader.biHeight = snapData->yPixels; pbmi->bmiHeader.biPlanes = 1; pbmi->bmiHeader.biBitCount = bitsPerPixel; pbmi->bmiHeader.biCompression = BI_RGB; pbmi->bmiHeader.biSizeImage = (LONG)linelength*snapData->yPixels; pbmi->bmiHeader.biXPelsPerMeter = 0x1711; /* 300 DPI */ pbmi->bmiHeader.biYPelsPerMeter = 0x1711; /* 300 DPI */ pbmi->bmiHeader.biClrUsed = ncolors; pbmi->bmiHeader.biClrImportant = ncolors; if (config->outputFormat == VPP_mono) for (x=0; xbmiColors[x].rgbBlue = (BYTE)x; pbmi->bmiColors[x].rgbRed = (BYTE)x; pbmi->bmiColors[x].rgbGreen = (BYTE)x; pbmi->bmiColors[x].rgbReserved = 0; } check(VPP_prepareSnap(snapData)); for (; numAverage > 0; numAverage--) { if (config->extTrigSnap) { check(VPP_extTrigSnap(10200)); /* max 255 frames integration = 10.2 sec */ } else if (config->flashSnap) { check(VPP_flashSnap()); } else { check(VPP_startSnap()); check(VPP_finishSnap()); } check(VPP_startReadout(config->outputFormat == VPP_mono ? VPP_mono : VPP_CbYCrY,0)); bitmappos = (BYTE VPP_huge *)pbmi + headerSize + (LONG)(snapData->yPixels-1)*avgLinelength; for (y=0; y < snapData->yPixels; y++) { check(VPP_readLine(linebuf,0,snapData->xPixels)); pAvg = (WORD VPP_far *)bitmappos; for (x=0; xyPixels; y++) { pAvg = (WORD VPP_far *)bitmappos; for (x=0; x 255) val = 255; linebuf[x] = (BYTE)val; } if (config->outputFormat == VPP_mono) #ifdef __WIN32__ memcpy(bitmappos2,linebuf,linelength); #else hmemcpy(bitmappos2,linebuf,linelength); #endif else { VPP_convertCbYCrYToBGR24(linebuf+avgLinelength/2,linebuf,snapData->xPixels); #ifdef __WIN32__ memcpy(bitmappos2,linebuf+avgLinelength/2,linelength); #else hmemcpy(bitmappos2,linebuf+avgLinelength/2,linelength); #endif } bitmappos += avgLinelength; bitmappos2 += linelength; } GlobalUnlock (hglb); GlobalFree (hglb); GlobalUnlock (*phDIB); GlobalReAlloc(*phDIB,headerSize+ (long)snapData->yPixels*linelength,GMEM_MOVEABLE); return VPP_success; } /****************************************************************************** ** Function name : VPX_filterDIB ** Description : Filters the input DIB with the specified filter. The ** DIB will shrink horizontally with the width of the ** filter - 1, and vertically with the height of the filter ** - 1. The filters may be of any size, and do not have to ** be quadratic. ** Parameters : hDIB = Handle to DIB which is to be filtered. The DIB ** must be generated by a VPX function to ensure the ** proper format, and the config->outputFormat value used ** when snapping the DIB must be one of the following: ** VPP_mono : 256 colors monochrome image ** VPP_BGR24 : 16M color image ** in WIN32 this format is also allowed: ** VPP_BGR032 : 32bit color image ** filter = pointer to filter structure: ** width: Width of the filter (must be >0) ** height: Height of the filter (must be >0) ** divideBy: Value to divide the calculated sum by ** doAbs: flag to calculate the absolute of the resulting ** image. Used e.g. with line detection filters. ** coeff: array of coefficients of the filter. Must be ** width*height characters long. May contain negative ** values. ** Return value : Errno = VPP_success, VPP_parameterOutOfRange, ** VPP_badPointer, VPP_outOfMemory ******************************************************************************/ VPP_Errno EXPORT VPX_filterDIB(HGLOBAL hDIB, VPX_Filter VPP_far *filter) { BITMAPINFO VPP_far *pbmi; BYTE VPP_huge *to; BYTE VPP_huge *from; DWORD linelength; DWORD newLinelength; DWORD newWidth; DWORD newHeight; DWORD newSize; DWORD headerSize; DWORD pixelWidth; int x,y,fx,fy,value; VPP_Char VPP_far *f; BYTE VPP_huge *pIn; BYTE VPP_huge *pOut; if (filter == NULL || hDIB == NULL) return VPP_badPointer; if (filter->width == 0 || filter->height == 0 || filter->divideBy == 0) return VPP_parameterOutOfRange; if ((pbmi = (BITMAPINFO VPP_far *)GlobalLock(hDIB)) == NULL) return VPP_outOfMemory; if (pbmi->bmiHeader.biWidth < filter->width || pbmi->bmiHeader.biHeight < filter->height || (pbmi->bmiHeader.biBitCount != 8 && pbmi->bmiHeader.biBitCount != 24 && pbmi->bmiHeader.biBitCount != 32)) { GlobalUnlock(hDIB); return VPP_parameterOutOfRange; } newWidth = pbmi->bmiHeader.biWidth-filter->width+1; newHeight = pbmi->bmiHeader.biHeight-filter->height+1; linelength = ((pbmi->bmiHeader.biWidth*pbmi->bmiHeader.biBitCount+31)/32)*4; newLinelength = ((newWidth*pbmi->bmiHeader.biBitCount+31)/32)*4; headerSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*pbmi->bmiHeader.biClrUsed; newSize = (LONG)newLinelength*newHeight + headerSize; pixelWidth = pbmi->bmiHeader.biBitCount/8; to = from = ((BYTE VPP_huge *)pbmi)+headerSize; for (y = newHeight; y > 0; y--) { pOut = to; for (x = pixelWidth*newWidth; x > 0; x--) { value = 0; f = filter->coeff; for (fy = filter->height; fy > 0; fy--) { pIn = from; for (fx = filter->width; fx > 0; fx--) { value += (int)(*f++)*(int)(*pIn); pIn += pixelWidth; } from += linelength; } from -= filter->height*linelength; value /= filter->divideBy; if (value < 0) value = filter->doAbs ? -value : 0; if (value > 255) value = 255; *pOut = (VPP_Byte)value; pOut ++; from ++; } from += linelength-pixelWidth*newWidth; to += newLinelength; } pbmi->bmiHeader.biWidth = newWidth; pbmi->bmiHeader.biHeight = newHeight; pbmi->bmiHeader.biSizeImage = (LONG)newLinelength*newHeight; GlobalUnlock(hDIB); GlobalReAlloc(hDIB,newSize,GMEM_MOVEABLE); return VPP_success; } /****************************************************************************** ** Function name : VPX_getFilter ** Description : Returns the predefined filter specified by the parameter ** Parameters : filterNo = number of the predefined filter. Must be ** one of the following: ** VPX_AVERAGE : calculates average of 3x3 pixels. ** Nice for removing severe noise. ** VPX_SMOOTH : a milder averaging filter ** VPX_DETAIL : enhances detail in the image ** VPX_SHARPEN : sharpens the edges in the image ** VPX_AI : "anti-interlace" removes interlace- ** effects caused by the 1/25 seconds time-delay ** between the two fields of a full video frame when ** the image is in motion. The image becomes very ** blurred near moving objects and slightly blurred ** elsewhere. ** VPX_AISHARPEN : AI combined with sharpen brings back ** the crispness after removing interlace-effects. ** VPX_VERTLINES : detects vertical lines ** VPX_HORIZLINES : detects horizontal lines ** Return value : predefined filter, or NULL if parameter out of range ******************************************************************************/ VPX_Filter VPP_far * EXPORT VPX_getFilter(int filterNo) { static VPX_Filter average = { 3, 3, 9, 0, "\1\1\1\1\1\1\1\1\1" }; static VPX_Filter smooth = { 3, 3,16, 0, "\1\1\1\1\10\1\1\1\1" }; static VPX_Filter detail = { 3, 3, 6, 0, "\0\377\0\377\012\377\0\377\0" }; static VPX_Filter sharpen = { 3, 3, 4, 0, "\1\374\1\374\20\374\1\374\1" }; static VPX_Filter AI = { 1, 3, 4, 0, "\1\2\1" }; static VPX_Filter AISharpen = { 3, 5,16, 0, "\1\374\1\376\10\376\372\30\372\376\10\376\1\374\1" }; static VPX_Filter vertLines = { 3, 3, 1, 1, "\377\0\1\376\0\2\377\0\1" }; static VPX_Filter horizLines = { 3, 3, 1, 1, "\377\376\377\0\0\0\1\2\1" }; switch (filterNo) { case VPX_AVERAGE: return &average; case VPX_SMOOTH: return &smooth; case VPX_DETAIL: return &detail; case VPX_SHARPEN: return &sharpen; case VPX_AI: return &AI; case VPX_AISHARPEN: return &AISharpen; case VPX_VERTLINES: return &vertLines; case VPX_HORIZLINES: return &horizLines; } return NULL; } /****************************************************************************** ** Function name : VPX_copyDIB ** Description : Duplicates a DIB ** Parameters : hDIB = Handle to DIB which is to be copied. The DIB ** must be generated by a VPX function to ensure the ** proper format. ** phDIB = pointer to handle to return the DIB copy in. ** Return value : Errno = VPP_success, VPP_badPointer, VPP_outOfMemory ******************************************************************************/ VPP_Errno EXPORT VPX_copyDIB(HANDLE hDIB, HANDLE VPP_far *phDIB) { BYTE VPP_far *srcDIB; BYTE VPP_far *dstDIB; DWORD size; if (hDIB == NULL || phDIB == NULL) return VPP_badPointer; *phDIB = NULL; size = GlobalSize(hDIB); if ((srcDIB = (BYTE VPP_far *)GlobalLock(hDIB)) == NULL || (*phDIB = GlobalAlloc(GMEM_MOVEABLE,size)) == NULL || (dstDIB = (BYTE VPP_far *)GlobalLock(*phDIB)) == NULL) return VPP_outOfMemory; #ifdef __WIN32__ memcpy(dstDIB,srcDIB,size); #else hmemcpy(dstDIB,srcDIB,size); #endif GlobalUnlock(*phDIB); GlobalUnlock(hDIB); return VPP_success; } /****************************************************************************** ** Function name : VPX_readIniFile ** Description : This function will read a complete MRT Imaging Card ** configuration from a *.INI file that has been saved ** previously. The configuration is first initialized using ** VPX_defaultConfig, and therefore it always contains a ** valid configuration on return, even if an error occurs. ** Parameters : filename : the file name and path to read the data from. ** sectionname : the name of the header of the section. ** config : The MRT Imaging Card configuration structure ** to be filled in. ** NOTE : When an error is returned from this function, the ** VPP_lastErrorFunctionName may not return the correct ** function name. ** Return value : Errno = VPP_success, VPP_badPointer, VPP_fileIOError or ** any error from VPX_defaultConfig. ******************************************************************************/ VPP_Errno EXPORT VPX_readIniFile (char VPP_far *filename, char VPP_far *sectionname, VPX_Config VPP_far *config) { char value[100]; int success; #define READ_INT(t,x,s) \ { if (success && \ GetPrivateProfileString(sectionname,s,"",value,100,filename)!=0) \ x = (t)atoi(value); \ else \ success = FALSE; } #define READ_FLOAT(t,x,s) \ { if (success && \ GetPrivateProfileString(sectionname,s,"",value,100,filename)!=0) \ x = (t)atof(value); \ else \ success = FALSE; } if (filename == NULL || sectionname == NULL || config == NULL) return VPP_badPointer; check(VPX_defaultConfig(config)); success = TRUE; READ_INT(VPP_SignalType,config->signalType,"SignalType"); READ_INT(int,config->inputChannel,"InputChannel"); READ_INT(int,config->brightness,"Brightness"); READ_INT(int,config->contrast,"Contrast"); READ_INT(int,config->saturation,"Saturation"); READ_INT(int,config->hue,"Hue"); READ_FLOAT(float,config->gamma,"Gamma"); READ_INT(VPP_Word,config->snapDataPAL.xOffset,"xOffsetPAL"); READ_INT(VPP_Word,config->snapDataPAL.xActive,"xActivePAL"); READ_INT(VPP_Word,config->snapDataPAL.xPixels,"xPixelsPAL"); READ_INT(VPP_Word,config->snapDataPAL.yOffset,"yOffsetPAL"); READ_INT(VPP_Word,config->snapDataPAL.yActive,"yActivePAL"); READ_INT(VPP_Word,config->snapDataPAL.yPixels,"yPixelsPAL"); READ_INT(VPP_Bool,config->snapDataPAL.interlaced,"interlacedPAL"); READ_INT(VPP_Word,config->snapDataNTSC.xOffset,"xOffsetNTSC"); READ_INT(VPP_Word,config->snapDataNTSC.xActive,"xActiveNTSC"); READ_INT(VPP_Word,config->snapDataNTSC.xPixels,"xPixelsNTSC"); READ_INT(VPP_Word,config->snapDataNTSC.yOffset,"yOffsetNTSC"); READ_INT(VPP_Word,config->snapDataNTSC.yActive,"yActiveNTSC"); READ_INT(VPP_Word,config->snapDataNTSC.yPixels,"yPixelsNTSC"); READ_INT(VPP_Bool,config->snapDataNTSC.interlaced,"interlacedNTSC"); READ_INT(VPP_ReadoutMode,config->outputFormat,"OutputFormat"); config->snapDataNTSC.monochrome = config->snapDataPAL.monochrome = (config->outputFormat == VPP_mono || config->outputFormat == VPP_mono4); READ_INT(VPP_Bool,config->extTrigSnap,"ExtTrig"); READ_INT(VPP_Bool,config->flashSnap,"Flash"); READ_INT(VPP_Bool,config->extTrigEnable,"ExtTrigEnable"); READ_INT(VPP_Bool,config->flashEnable,"FlashEnable"); READ_INT(VPP_Bool,config->mono4Enable,"Gray16Enable"); READ_INT(VPP_Bool,config->monoEnable,"Gray256Enable"); READ_INT(VPP_Bool,config->RGB8Enable,"Color256Enable"); READ_INT(VPP_Bool,config->BGR24Enable,"Color16MEnable"); #ifdef __WIN32__ if (success) { READ_INT(VPP_Bool,config->RGB15Enable,"Color32kEnable"); READ_INT(VPP_Bool,config->RGB16Enable,"Color64kEnable"); READ_INT(VPP_Bool,config->BGR032Enable,"Color32bitEnable"); success = TRUE; // Ignore error on these formats } #endif #undef READ_INT #undef READ_FLOAT if (!success) { #ifndef VPX_NO_MESSAGES MessageBox (NULL, "Error when reading INI file.","Error", MB_OK); #endif return VPP_fileIOError; } return VPP_success; } /****************************************************************************** ** Function name : VPX_saveInfFile ** Description : This function will save a complete MRT Imaging Card ** configuration to a *.INI file so that it can be restored ** at a later time. ** Parameters : filename : the file name and path to store the data in. ** sectionname : the name of the header of the section. ** config : The MRT Imaging Card configuration structure ** to be stored. ** NOTE : When an error is returned from this function, the ** VPP_lastErrorFunctionName may not return the correct ** function name. ** Return value : Errno = VPP_success, VPP_badPointer or VPP_fileIOError. ******************************************************************************/ VPP_Errno EXPORT VPX_saveIniFile (char VPP_far *filename, char VPP_far *sectionname, VPX_Config VPP_far *config) { char value[100]; int success; #define WRITE_INT(x,s) \ { if (success) { \ sprintf(value,"%i",x); \ success = (success && WritePrivateProfileString(sectionname,s,value,filename)); } } #define WRITE_FLOAT(x,s) \ { if (success) { \ sprintf(value,"%.2f",x); \ success = (success && WritePrivateProfileString(sectionname,s,value,filename)); } } if (filename == NULL || sectionname == NULL || config == NULL) return VPP_badPointer; success = TRUE; WRITE_INT(config->signalType,"SignalType"); WRITE_INT(config->inputChannel,"InputChannel"); WRITE_INT(config->brightness,"Brightness"); WRITE_INT(config->contrast,"Contrast"); WRITE_INT(config->saturation,"Saturation"); WRITE_INT(config->hue,"Hue"); WRITE_FLOAT(config->gamma,"Gamma"); WRITE_INT(config->snapDataPAL.xOffset,"xOffsetPAL"); WRITE_INT(config->snapDataPAL.xActive,"xActivePAL"); WRITE_INT(config->snapDataPAL.xPixels,"xPixelsPAL"); WRITE_INT(config->snapDataPAL.yOffset,"yOffsetPAL"); WRITE_INT(config->snapDataPAL.yActive,"yActivePAL"); WRITE_INT(config->snapDataPAL.yPixels,"yPixelsPAL"); WRITE_INT(config->snapDataPAL.interlaced,"interlacedPAL"); WRITE_INT(config->snapDataNTSC.xOffset,"xOffsetNTSC"); WRITE_INT(config->snapDataNTSC.xActive,"xActiveNTSC"); WRITE_INT(config->snapDataNTSC.xPixels,"xPixelsNTSC"); WRITE_INT(config->snapDataNTSC.yOffset,"yOffsetNTSC"); WRITE_INT(config->snapDataNTSC.yActive,"yActiveNTSC"); WRITE_INT(config->snapDataNTSC.yPixels,"yPixelsNTSC"); WRITE_INT(config->snapDataNTSC.interlaced,"interlacedNTSC"); WRITE_INT(config->outputFormat,"OutputFormat"); WRITE_INT(config->extTrigSnap,"ExtTrig"); WRITE_INT(config->flashSnap,"Flash"); WRITE_INT(config->extTrigEnable,"ExtTrigEnable"); WRITE_INT(config->flashEnable,"FlashEnable"); WRITE_INT(config->mono4Enable,"Gray16Enable"); WRITE_INT(config->monoEnable,"Gray256Enable"); WRITE_INT(config->RGB8Enable,"Color256Enable"); WRITE_INT(config->BGR24Enable,"Color16MEnable"); #ifdef __WIN32__ WRITE_INT(config->RGB15Enable,"Color32kEnable"); WRITE_INT(config->RGB16Enable,"Color64kEnable"); WRITE_INT(config->BGR032Enable,"Color32bitEnable"); #endif #undef WRITE_INT #undef WRITE_FLOAT if (!success) { #ifndef VPX_NO_MESSAGES MessageBox (NULL, "Error when writing to INI file.","Error", MB_OK); #endif return VPP_fileIOError; } return VPP_success; } /****************************************************************************** ** Function name : VPX_defaultPalette ** Description : This function will set up a color palette which the ** VPX_draw function will use to draw the pictures on the ** screen. ** Parameters : hDC is a handle to the device context which will be ** used in VPX_draw. ** monochrome is a flag to tell the function to create a ** monochrome palette instead of color. ** NOTE : The VPP_lastErrorFunctionName will not return the correct ** function name. ** Return value : VPP_success is returned if the color palette is set up ** as planned. VPP_outOfMemory is returned if the memory ** needed for the function (palette) could not be claimed, ** or locked. VPP_badPointer is returned if the display ** only support 16 colors. No realisation of a ** palette possible. ******************************************************************************/ VPP_Errno EXPORT VPX_defaultPalette (HDC hdc, VPP_Bool monochrome) { int loop; int colors; HGLOBAL paletteHandle; LOGPALETTE VPP_far *pointer; colors = ((DWORD) 1) << (GetDeviceCaps (hdc,PLANES) * GetDeviceCaps (hdc,BITSPIXEL)); if (colors > 256) { return VPP_success; } else if (colors == 256) { paletteHandle = GlobalAlloc (GMEM_MOVEABLE,sizeof (LOGPALETTE) + colors * sizeof (PALETTEENTRY)); if (paletteHandle == NULL) { return VPP_outOfMemory; } pointer = (LOGPALETTE VPP_far *) GlobalLock (paletteHandle); if (pointer == NULL) { GlobalFree (paletteHandle); return VPP_outOfMemory; } pointer->palVersion = 0x300; pointer->palNumEntries = (WORD) colors; for (loop = 0; loop < colors; loop++) { if (monochrome) { // Setting up 256 monochrome palette. pointer->palPalEntry[loop].peRed = (BYTE) loop; pointer->palPalEntry[loop].peGreen = (BYTE) loop; pointer->palPalEntry[loop].peBlue = (BYTE) loop; pointer->palPalEntry[loop].peFlags = PC_NOCOLLAPSE; } else { // Setting up a 256 color palette, evenly spread out pointer->palPalEntry[loop].peRed = (BYTE)(((loop >> 5)&7)*73/2); pointer->palPalEntry[loop].peGreen = (BYTE)(((loop >> 2)&7)*73/2); pointer->palPalEntry[loop].peBlue = (BYTE)((loop & 3)*85); pointer->palPalEntry[loop].peFlags = PC_NOCOLLAPSE; } } VPX_palette = CreatePalette (pointer); GlobalUnlock (paletteHandle); GlobalFree (paletteHandle); if (VPX_palette == NULL) { return VPP_outOfMemory; } } else { return VPP_badPointer; } return VPP_success; } /****************************************************************************** ** Function name : VPX_releasePalette ** Description : This function will delete the custom palette and make ** the windows default palette the one which will be used ** to draw the images. ** Parameters : void ** NOTE : The VPP_lastErrorFunctionName may not return the correct ** function name. ** Return value : VPP_success if a palette was deleted, and VPP_badPointer ** if function failed or no palette was defined when the ** function was called. ******************************************************************************/ VPP_Errno EXPORT VPX_releasePalette (void) { if (VPX_palette != NULL) { if (DeleteObject (VPX_palette) == 0) { return VPP_badPointer; } VPX_palette = NULL; } return VPP_success; } #ifndef VPX_NO_DIALOG static VPP_Char dialogScroll (HWND hDlg, int nScrollCode, int nPos, HWND hwndScrollBar, VPX_Config VPP_far *config); static void initDialog (HWND hDlg, VPX_Config VPP_far *config); static void defaultData (VPX_Config VPP_far *config); static void inputFields (HWND hDlg, WORD wID, VPX_Config VPP_far *config); static void mouseMove (HWND hDlg, POINT *first, LPARAM lParam, VPX_Config VPP_far *config); static void lButtonDown (HWND hDlg, POINT *first, LPARAM lParam, VPX_Config VPP_far *config); static int VPP_far PASCAL formatDlgProc(HWND hDlg, WORD msg, WPARAM wParam, LPARAM lParam); /****************************************************************************** ** Function name : VPX_formatDialogBox ** Description : This function will display the format dialog box on the ** screen. ** Parameters : hinst : a handle to an application instance. ** parent : is a handle to the parent window. ** config : is the pointer to the VPX_Config structure ** which will be set up. ** NOTE : There is no error checking in this function. You should ** not call this function before you have successfully ** snapped an image, because if an error occurs in this ** function you will not know it. ** Return value : IDOK if "OK" was pressed, otherwise IDCANCEL ******************************************************************************/ int EXPORT VPX_formatDialogBox (HINSTANCE hinst, HWND parent, VPX_Config VPP_far *config) { int result; #ifndef __DLL__ if (config == NULL) return -1; #ifdef __WIN32__ Ctl3dRegister(hinst); Ctl3dAutoSubclass(hinst); #endif result = DialogBoxParam (hinst, MAKEINTRESOURCE (DLG_FORMAT), parent, formatDlgProc, (LONG) config); #ifdef __WIN32__ Ctl3dUnregister(hinst); #endif return result; #else /* __DLL__ */ HANDLE hLibrary; if (config == NULL) return -1; #ifdef __WIN32__ hLibrary = LoadLibrary ("VPX32.DLL"); Ctl3dRegister(hLibrary); Ctl3dAutoSubclass(hLibrary); #else hLibrary = LoadLibrary ("VPX.DLL"); #endif result = DialogBoxParam (hLibrary, MAKEINTRESOURCE (DLG_FORMAT), parent, formatDlgProc, (LONG) config); #ifdef __WIN32__ Ctl3dUnregister(hLibrary); #endif FreeLibrary (hLibrary); return result; #endif /* __DLL__ */ } /****************************************************************************** ** Function name : formatDialogProc ** Description : This function receives all the messages from the format ** dialog box. When the function is called the first time ** a pointer to a VPX_Config structure is sent through ** the lParam variable. This structure will be filled ** with data from the dialog box. ** Parameters : All variables are automatically generated by windows, except ** the first time called, when the lParam variable contains ** a pointer to a VPX_Config structure. ** NOTE : static function only used by the dialog box function ** Return value : This function will return IDOK or IDCANCEL. ******************************************************************************/ static int VPP_far PASCAL formatDlgProc(HWND hDlg, WORD msg, WPARAM wParam, LPARAM lParam) { HDC hDC; static VPX_Config VPP_far *data = NULL; // snap data for the calling window. static VPX_Config oldData; // Storing the old values in case CANCEL is pressed VPX_Config config; // config for drawing preview image. static UINT timer = 2; static VPP_LimitData limitData; static POINT first; static VPP_VideoStandard oldVideoStandard; static VPP_Bool dontChangeInputFields = 0; static VPP_Bool releasePaletteOnExit; HGDIOBJ object; switch (msg) { case WM_INITDIALOG : data = (VPX_Config VPP_far*) lParam; oldData = *data; VPX_prepare(data, VPP_false); oldVideoStandard = data->videoStandard; dontChangeInputFields = VPP_true; initDialog (hDlg, data); dontChangeInputFields = VPP_false; VPP_getLimits (data->videoStandard, &limitData); SetTimer (hDlg, timer, 1,NULL); first.x = -1; if (VPX_palette == NULL) { releasePaletteOnExit = VPP_true; } else { VPX_releasePalette(); releasePaletteOnExit = VPP_false; } hDC = GetDC(hDlg); VPX_defaultPalette(hDC, (data->outputFormat == VPP_mono4 || data->outputFormat == VPP_mono)); ReleaseDC(hDlg,hDC); return TRUE; case WM_TIMER : if (data != NULL) { RECT size; int x1,x2,y1,y2; VPP_SnapData VPP_far *snapData; VPX_prepare(data, VPP_false); if (oldVideoStandard != data->videoStandard) { dontChangeInputFields = VPP_true; initDialog (hDlg, data); dontChangeInputFields = VPP_false; VPP_getLimits (data->videoStandard, &limitData); } oldVideoStandard = data->videoStandard; snapData = (data->videoStandard == VPP_PAL ? &data->snapDataPAL : &data->snapDataNTSC); GetClientRect (GetDlgItem (hDlg, IDC_PREVIEW), &size); // Calculating the mapped point on the preview window. x1 = (int)(snapData->xOffset / (limitData.xActiveMax / (float) size.right)); x2 = (int)((snapData->xActive + snapData->xOffset) / (limitData.xActiveMax / (float) size.right)); if (x2 > size.right) { x2 = size.right; } if (snapData->interlaced) { y2 = (int)((snapData->yActive + snapData->yOffset) / (limitData.yActiveMax / (float) size.bottom)); y1 = (int)(snapData->yOffset / (limitData.yActiveMax / (float) size.bottom)); } else { y2 = (int)((snapData->yActive * 2 + snapData->yOffset * 2) / (limitData.yActiveMax / (float) size.bottom)); y1 = (int)(snapData->yOffset * 2 / (limitData.yActiveMax / (float) size.bottom)); } if (y2 > size.bottom) { y2 = size.bottom; } config = *data; snapData = (config.videoStandard == VPP_PAL ? &config.snapDataPAL : &config.snapDataNTSC); snapData->xOffset = 0; snapData->yOffset = 0; snapData->xActive = limitData.xActiveMax; snapData->yActive = limitData.yActiveMax / 2; snapData->xPixels = (VPP_Word)size.right+1; snapData->yPixels = (VPP_Word)size.bottom+1; snapData->interlaced = VPP_false; snapData->monochrome = (config.outputFormat == VPP_mono || config.outputFormat == VPP_mono4); config.extTrigSnap = VPP_false; config.flashSnap = VPP_false; VPX_snap (&config); // snaping image. hDC = GetDC (GetDlgItem (hDlg, IDC_PREVIEW)); VPX_draw (hDC, &config, VPX_DEFAULT, VPX_DEFAULT, VPX_DEFAULT, VPX_DEFAULT); // Drawing image. object = SelectObject (hDC, GetStockObject (WHITE_PEN)); // Drawing the square with a white pen. MoveToEx (hDC, x1 , y1, NULL); LineTo (hDC, x2, y1); LineTo (hDC, x2, y2); LineTo (hDC, x1, y2); LineTo (hDC, x1, y1); DeleteObject (object); ReleaseDC (GetDlgItem (hDlg, IDC_PREVIEW), hDC); } break; case WM_VSCROLL : { int nScrollCode; int nPos; HWND hwndScrollBar; #ifdef __WIN32__ nScrollCode = (int) LOWORD(wParam); // scroll bar value nPos = (int) HIWORD(wParam); // scroll box position hwndScrollBar = (HWND) lParam; // handle of scroll bar #else nScrollCode = (int) wParam; /* scroll bar code */ nPos = (int)LOWORD(lParam); /* current scroll box position */ hwndScrollBar = (HWND)HIWORD(lParam); /* handle of the control */ #endif if (nScrollCode != SB_ENDSCROLL) { dialogScroll (hDlg, nScrollCode, nPos, hwndScrollBar, data); } return FALSE; } case WM_LBUTTONDOWN : dontChangeInputFields = VPP_true; lButtonDown (hDlg, &first, lParam, data); dontChangeInputFields = VPP_false; break; case WM_MOUSEMOVE : if ((wParam == MK_LBUTTON) && (first.x != -1)) { dontChangeInputFields = VPP_true; mouseMove (hDlg, &first, lParam, data); dontChangeInputFields = VPP_false; } break; case WM_COMMAND : { WORD wNotifyCode; WORD wID; // HWND hwndCtl; #ifdef __WIN32__ wNotifyCode = HIWORD(wParam); // notification code wID = LOWORD(wParam); // item, control, or accelerator identifier // hwndCtl = (HWND) lParam; // handle of control #else wID = wParam; /* control or menu item identifier */ // hwndCtl = (HWND) LOWORD(lParam); /* handle of control */ wNotifyCode = HIWORD(lParam); /* notification message */ #endif if (data != NULL) switch (wID) { case IDC_EDX1: case IDC_EDY1: case IDC_EDX2: case IDC_EDY2: case IDC_EDHEIGHT: case IDC_EDWIDTH: if (!dontChangeInputFields) { if (wNotifyCode != EN_KILLFOCUS) { inputFields (hDlg, wID, data); VPX_prepare(data,VPP_false); } else { dontChangeInputFields = VPP_true; inputFields (hDlg, 0, data);// Will enter default mode in func. dontChangeInputFields = VPP_false; } } break; case IDC_CBINTERLACED: { VPP_SnapData VPP_far *snapData; snapData = (data->videoStandard == VPP_PAL ? &data->snapDataPAL : &data->snapDataNTSC); if (snapData->interlaced) { snapData->interlaced = VPP_false; snapData->xPixels /= 2; snapData->yOffset /= 2; snapData->yActive /= 2; snapData->yPixels /= 2; } else { snapData->interlaced = VPP_true; snapData->xPixels *= 2; snapData->yOffset *= 2; snapData->yActive *= 2; snapData->yPixels *= 2; } dontChangeInputFields = VPP_true; VPX_prepare(data,VPP_false); inputFields (hDlg, 0, data); dontChangeInputFields = VPP_false; break; } case IDC_CBEXTTRIG: { data->extTrigSnap = SendDlgItemMessage(hDlg, IDC_CBEXTTRIG, BM_GETCHECK, 0, 0); if (data->extTrigSnap && data->flashSnap) { data->flashSnap = VPP_false; SendDlgItemMessage(hDlg, IDC_CBFLASH, BM_SETCHECK, 0, 0); } break; } case IDC_CBFLASH: { data->flashSnap = SendDlgItemMessage(hDlg, IDC_CBFLASH, BM_GETCHECK, 0, 0); if (data->extTrigSnap && data->flashSnap) { data->extTrigSnap = VPP_false; SendDlgItemMessage(hDlg, IDC_CBEXTTRIG, BM_SETCHECK, 0, 0); } break; } case IDC_COMBOOUTPUT: { VPP_ReadoutMode oldFormat; int cursel,i; oldFormat = data->outputFormat; cursel = SendDlgItemMessage(hDlg, IDC_COMBOOUTPUT, CB_GETCURSEL, 0, 0); i = 0; if (data->mono4Enable) { if (cursel == i) data->outputFormat = VPP_mono4; i++; } if (data->monoEnable) { if (cursel == i) data->outputFormat = VPP_mono; i++; } if (data->RGB8Enable) { if (cursel == i) data->outputFormat = VPP_RGB8; i++; } #ifdef __WIN32__ if (data->RGB15Enable) { if (cursel == i) data->outputFormat = VPP_RGB15; i++; } if (data->RGB16Enable) { if (cursel == i) data->outputFormat = VPP_RGB16; i++; } #endif if (data->BGR24Enable) { if (cursel == i) data->outputFormat = VPP_BGR24; i++; } #ifdef __WIN32__ if (data->BGR032Enable) { if (cursel == i) data->outputFormat = VPP_BGR032; i++; } #endif if (cursel >= i) // Fall-back on BGR24 data->outputFormat = VPP_BGR24; if ((oldFormat == VPP_mono4 || oldFormat == VPP_mono) ^ (data->outputFormat == VPP_mono4 || data->outputFormat == VPP_mono)) { if (data->outputFormat == VPP_mono4 || data->outputFormat == VPP_mono) { ShowWindow(GetDlgItem(hDlg,IDC_SBSATURATION), SW_HIDE); ShowWindow(GetDlgItem(hDlg,IDC_EBSATURATION), SW_HIDE); ShowWindow(GetDlgItem(hDlg,IDC_ETSATURATION), SW_HIDE); ShowWindow(GetDlgItem(hDlg,IDC_SBHUE), SW_HIDE); ShowWindow(GetDlgItem(hDlg,IDC_EBHUE), SW_HIDE); ShowWindow(GetDlgItem(hDlg,IDC_ETHUE), SW_HIDE); hDC = GetDC(hDlg); VPX_releasePalette(); VPX_defaultPalette(hDC,VPP_true); ReleaseDC(hDlg,hDC); } else { ShowWindow(GetDlgItem(hDlg,IDC_SBSATURATION), SW_SHOW); ShowWindow(GetDlgItem(hDlg,IDC_EBSATURATION), SW_SHOW); ShowWindow(GetDlgItem(hDlg,IDC_ETSATURATION), SW_SHOW); if (data->videoStandard != VPP_PAL) { ShowWindow(GetDlgItem(hDlg,IDC_SBHUE), SW_SHOW); ShowWindow(GetDlgItem(hDlg,IDC_EBHUE), SW_SHOW); ShowWindow(GetDlgItem(hDlg,IDC_ETHUE), SW_SHOW); } hDC = GetDC(hDlg); VPX_releasePalette(); VPX_defaultPalette(hDC,VPP_false); ReleaseDC(hDlg,hDC); } } break; } case IDC_COMBOSIGNALTYPE: switch (SendDlgItemMessage(hDlg, IDC_COMBOSIGNALTYPE, CB_GETCURSEL, 0, 0)) { case 0: data->signalType = VPP_composite; break; case 1: data->signalType = VPP_Svideo; break; } break; case IDC_PBDEFAULT : VPP_testSignal (&data->videoStandard); defaultData (data); dontChangeInputFields = VPP_true; initDialog (hDlg, data); dontChangeInputFields = VPP_false; break; case IDOK : dontChangeInputFields = VPP_true; inputFields (hDlg, 0, data); dontChangeInputFields = VPP_false; VPX_prepare (data, VPP_false); data = NULL; if (releasePaletteOnExit) VPX_releasePalette(); KillTimer (hDlg, timer); EndDialog(hDlg, IDOK); break; case IDCANCEL : *data = oldData; VPX_prepare (data, VPP_false); data = NULL; if (releasePaletteOnExit) VPX_releasePalette(); KillTimer (hDlg, timer); EndDialog(hDlg, IDCANCEL); break; } } } return FALSE; } /****************************************************************************** ** Function name : defaultData ** Description : This function will set up the default values for the ** VPX_Config structure. This is used when the Default ** push button is pressed on the format dialog box. ** brightness, contrast, saturation and hue is set to zero. ** Depending on config->videoStandard, one of ** config->snapDataPAL and config->snapDataNTSC will be ** filled with data from VPP_autoCrop. ** Parameters : config : This is the VPX_Config structure which ** will be filled with the default data. ** NOTE : static function only used by the dialog box function ******************************************************************************/ static void defaultData (VPX_Config VPP_far *data) { VPP_SnapData VPP_far *snapData; snapData = (data->videoStandard == VPP_PAL ? &data->snapDataPAL : &data->snapDataNTSC); data->brightness = VPP_DEFAULT_BRIGHTNESS; data->contrast = VPP_DEFAULT_CONTRAST; data->saturation = VPP_DEFAULT_SATURATION; data->hue = VPP_DEFAULT_HUE; VPP_setBrightness((VPP_Char)data->brightness); VPP_setContrast ((VPP_Char)data->contrast); VPP_setSaturation((VPP_Char)data->saturation); VPP_setHue ((VPP_Char)data->hue); snapData->xPixels = 0; snapData->yPixels = 0; VPP_autoCrop (snapData); if (data->videoStandard == VPP_PAL) snapData->xPixels = (VPP_Word)((snapData->xActive*768L+920/2)/920L); else snapData->xPixels = (VPP_Word)((snapData->xActive*640L+754/2)/754L); if (snapData->interlaced == VPP_false) snapData->xPixels /= 2; snapData->yPixels = snapData->yActive; #ifdef VPP_NO_STRETCH_IMAGE { VPP_LimitData limitData; VPP_getLimits(data->videoStandard,&limitData); if (snapData->xPixels > limitData.xPixelsMax) { snapData->yPixels = (VPP_Word)((long)snapData->yPixels* limitData.xPixelsMax/snapData->xPixels); snapData->xPixels = limitData.xPixelsMax; } } #endif /* VPP_STRETCH_IMAGE */ } /****************************************************************************** ** Function name : initDialog ** Description : This function will set up the dialog box so all the ** fields contain the right value and scroll bars are placed ** correctly. It will also set up the VPP_SnapData structure ** which is used to snap and draw the image on the dialog box. ** Parameters : hDlg : handle to the dialog box. ** data : the VPX_Config structure sent to the dialog ** box from the user. ** NOTE : static function only used by the dialog box function ******************************************************************************/ static void initDialog (HWND hDlg, VPX_Config VPP_far *data) { VPP_SnapData VPP_far *snapData; int i; snapData = (data->videoStandard == VPP_PAL ? &data->snapDataPAL : &data->snapDataNTSC); SendDlgItemMessage(hDlg, IDC_COMBOSIGNALTYPE, CB_RESETCONTENT, 0, 0); #ifdef VPP_GERMAN SendDlgItemMessage(hDlg, IDC_COMBOSIGNALTYPE, CB_INSERTSTRING, 0, (LONG)((LPSTR)"BAS")); #else SendDlgItemMessage(hDlg, IDC_COMBOSIGNALTYPE, CB_INSERTSTRING, 0, (LONG)((LPSTR)"Composite")); #endif SendDlgItemMessage(hDlg, IDC_COMBOSIGNALTYPE, CB_INSERTSTRING, 1, (LONG)((LPSTR)"S-Video")); SendDlgItemMessage(hDlg, IDC_COMBOSIGNALTYPE, CB_SETCURSEL, data->signalType==VPP_composite ? 0 : 1, 0); SendDlgItemMessage(hDlg, IDC_COMBOOUTPUT, CB_RESETCONTENT, 0, 0); i = 0; if (data->mono4Enable) { #ifdef VPP_GERMAN SendDlgItemMessage(hDlg, IDC_COMBOOUTPUT, CB_INSERTSTRING, i, (LONG)((LPSTR)"16 Graustufen")); #else SendDlgItemMessage(hDlg, IDC_COMBOOUTPUT, CB_INSERTSTRING, i, (LONG)((LPSTR)"16 gray levels")); #endif if (data->outputFormat == VPP_mono4) SendDlgItemMessage(hDlg, IDC_COMBOOUTPUT, CB_SETCURSEL, i, 0); i++; } if (data->monoEnable) { #ifdef VPP_GERMAN SendDlgItemMessage(hDlg, IDC_COMBOOUTPUT, CB_INSERTSTRING, i, (LONG)((LPSTR)"256 Graustufen")); #else SendDlgItemMessage(hDlg, IDC_COMBOOUTPUT, CB_INSERTSTRING, i, (LONG)((LPSTR)"256 gray levels")); #endif if (data->outputFormat == VPP_mono) SendDlgItemMessage(hDlg, IDC_COMBOOUTPUT, CB_SETCURSEL, i, 0); i++; } if (data->RGB8Enable) { #ifdef VPP_GERMAN SendDlgItemMessage(hDlg, IDC_COMBOOUTPUT, CB_INSERTSTRING, i, (LONG)((LPSTR)"256 Farben")); #else SendDlgItemMessage(hDlg, IDC_COMBOOUTPUT, CB_INSERTSTRING, i, (LONG)((LPSTR)"256 colors")); #endif if (data->outputFormat == VPP_RGB8) SendDlgItemMessage(hDlg, IDC_COMBOOUTPUT, CB_SETCURSEL, i, 0); i++; } #ifdef __WIN32__ if (data->RGB15Enable) { #ifdef VPP_GERMAN SendDlgItemMessage(hDlg, IDC_COMBOOUTPUT, CB_INSERTSTRING, i, (LONG)((LPSTR)"32k Farben")); #else SendDlgItemMessage(hDlg, IDC_COMBOOUTPUT, CB_INSERTSTRING, i, (LONG)((LPSTR)"32k colors")); #endif if (data->outputFormat == VPP_RGB15) SendDlgItemMessage(hDlg, IDC_COMBOOUTPUT, CB_SETCURSEL, i, 0); i++; } if (data->RGB16Enable) { #ifdef VPP_GERMAN SendDlgItemMessage(hDlg, IDC_COMBOOUTPUT, CB_INSERTSTRING, i, (LONG)((LPSTR)"64k Farben")); #else SendDlgItemMessage(hDlg, IDC_COMBOOUTPUT, CB_INSERTSTRING, i, (LONG)((LPSTR)"64k colors")); #endif if (data->outputFormat == VPP_RGB16) SendDlgItemMessage(hDlg, IDC_COMBOOUTPUT, CB_SETCURSEL, i, 0); i++; } #endif if (data->BGR24Enable) { #ifdef VPP_GERMAN SendDlgItemMessage(hDlg, IDC_COMBOOUTPUT, CB_INSERTSTRING, i, (LONG)((LPSTR)"16M Farben")); #else SendDlgItemMessage(hDlg, IDC_COMBOOUTPUT, CB_INSERTSTRING, i, (LONG)((LPSTR)"16M colors")); #endif if (data->outputFormat == VPP_BGR24) SendDlgItemMessage(hDlg, IDC_COMBOOUTPUT, CB_SETCURSEL, i, 0); i++; } #ifdef __WIN32__ if (data->BGR032Enable) { #ifdef VPP_GERMAN SendDlgItemMessage(hDlg, IDC_COMBOOUTPUT, CB_INSERTSTRING, i, (LONG)((LPSTR)"32bit Farben")); #else SendDlgItemMessage(hDlg, IDC_COMBOOUTPUT, CB_INSERTSTRING, i, (LONG)((LPSTR)"32bit colors")); #endif if (data->outputFormat == VPP_BGR032) SendDlgItemMessage(hDlg, IDC_COMBOOUTPUT, CB_SETCURSEL, i, 0); i++; } #endif if (i == 0) // Fall-back on BGR24 { #ifdef VPP_GERMAN SendDlgItemMessage(hDlg, IDC_COMBOOUTPUT, CB_INSERTSTRING, i, (LONG)((LPSTR)"16M Farben")); #else SendDlgItemMessage(hDlg, IDC_COMBOOUTPUT, CB_INSERTSTRING, i, (LONG)((LPSTR)"16M colors")); #endif SendDlgItemMessage(hDlg, IDC_COMBOOUTPUT, CB_SETCURSEL, i, 0); } EnableWindow(GetDlgItem(hDlg,IDC_COMBOOUTPUT),i>1); ShowWindow(GetDlgItem(hDlg,IDC_CBEXTTRIG),data->extTrigEnable ? SW_SHOW : SW_HIDE); ShowWindow(GetDlgItem(hDlg,IDC_CBFLASH ),data->flashEnable ? SW_SHOW : SW_HIDE); SendDlgItemMessage(hDlg, IDC_CBEXTTRIG, BM_SETCHECK, data->extTrigSnap, 0); SendDlgItemMessage(hDlg, IDC_CBFLASH , BM_SETCHECK, data->flashSnap , 0); SetScrollRange (GetDlgItem (hDlg, IDC_SBCONTRAST), SB_CTL, -127, 127, FALSE); SetScrollPos (GetDlgItem (hDlg, IDC_SBCONTRAST), SB_CTL, -data->contrast, TRUE); SetDlgItemInt (hDlg, IDC_EBCONTRAST, (data->contrast*100)/127, TRUE); SetScrollRange (GetDlgItem (hDlg, IDC_SBBRIGHTNESS), SB_CTL, -127, 127, FALSE); SetScrollPos (GetDlgItem (hDlg, IDC_SBBRIGHTNESS), SB_CTL, -data->brightness, TRUE); SetDlgItemInt (hDlg, IDC_EBBRIGHTNESS, (data->brightness*100)/127, TRUE); SetScrollRange (GetDlgItem (hDlg, IDC_SBSATURATION), SB_CTL, -127, 127, FALSE); SetScrollPos (GetDlgItem (hDlg, IDC_SBSATURATION), SB_CTL, -data->saturation, TRUE); SetDlgItemInt (hDlg, IDC_EBSATURATION, (data->saturation*100)/127, TRUE); if (data->videoStandard == VPP_PAL) data->hue = 0; SetScrollRange (GetDlgItem (hDlg, IDC_SBHUE), SB_CTL, -127, 127, FALSE); SetScrollPos (GetDlgItem (hDlg, IDC_SBHUE), SB_CTL, -data->hue, TRUE); SetDlgItemInt (hDlg, IDC_EBHUE, (data->hue*100)/127, TRUE); if (data->outputFormat == VPP_mono || data->outputFormat == VPP_mono4) { ShowWindow(GetDlgItem(hDlg,IDC_SBSATURATION), SW_HIDE); ShowWindow(GetDlgItem(hDlg,IDC_EBSATURATION), SW_HIDE); ShowWindow(GetDlgItem(hDlg,IDC_ETSATURATION), SW_HIDE); ShowWindow(GetDlgItem(hDlg,IDC_SBHUE), SW_HIDE); ShowWindow(GetDlgItem(hDlg,IDC_EBHUE), SW_HIDE); ShowWindow(GetDlgItem(hDlg,IDC_ETHUE), SW_HIDE); } else { ShowWindow(GetDlgItem(hDlg,IDC_SBSATURATION), SW_SHOW); ShowWindow(GetDlgItem(hDlg,IDC_EBSATURATION), SW_SHOW); ShowWindow(GetDlgItem(hDlg,IDC_ETSATURATION), SW_SHOW); if (data->videoStandard == VPP_PAL) { ShowWindow(GetDlgItem(hDlg,IDC_SBHUE), SW_HIDE); ShowWindow(GetDlgItem(hDlg,IDC_EBHUE), SW_HIDE); ShowWindow(GetDlgItem(hDlg,IDC_ETHUE), SW_HIDE); } else { ShowWindow(GetDlgItem(hDlg,IDC_SBHUE), SW_SHOW); ShowWindow(GetDlgItem(hDlg,IDC_EBHUE), SW_SHOW); ShowWindow(GetDlgItem(hDlg,IDC_ETHUE), SW_SHOW); } } CheckDlgButton(hDlg, IDC_CBINTERLACED, snapData->interlaced); SetDlgItemInt (hDlg, IDC_EDX1, snapData->xOffset, FALSE); SetDlgItemInt (hDlg, IDC_EDY1, snapData->yOffset, FALSE); SetDlgItemInt (hDlg, IDC_EDX2, snapData->xActive, FALSE); SetDlgItemInt (hDlg, IDC_EDY2, snapData->yActive, FALSE); SetDlgItemInt (hDlg, IDC_EDWIDTH , snapData->xPixels, FALSE); SetDlgItemInt (hDlg, IDC_EDHEIGHT, snapData->yPixels, FALSE); if (data->videoStandard == VPP_PAL) SetDlgItemText (hDlg, IDC_VIDEOSTANDARD, " PAL"); else if (data->videoStandard == VPP_NTSC) SetDlgItemText (hDlg, IDC_VIDEOSTANDARD, " NTSC"); else SetDlgItemText (hDlg, IDC_VIDEOSTANDARD, " No signal"); } /****************************************************************************** ** Function name : dialogScroll ** Description : A function called when one of the scroll bars are ** activated or changed. ** Parameters : hDlg : Handle to the dialog box window. ** nScrollCode : scroll bar code ** nPos : current scroll box position ** hwndScrollBar : handle of the control ** data : the VPX_Config structure sent to the dialog ** box from the user. ** NOTE : Static function only used by the dialog box function. ** Return value : returns the scroll position of the scroll bar. ******************************************************************************/ static VPP_Char dialogScroll (HWND hDlg, int nScrollCode, int nPos, HWND hwndScrollBar, VPX_Config VPP_far *data) { VPP_Char val = 0; switch (nScrollCode) { case SB_LINEUP: val = GetScrollPos (hwndScrollBar, SB_CTL); if (val == -127) return val; val --; SetScrollPos (hwndScrollBar, SB_CTL, val, TRUE); break; case SB_LINEDOWN : val = GetScrollPos (hwndScrollBar, SB_CTL); if (val == 127) return val; val ++; SetScrollPos (hwndScrollBar, SB_CTL, val, TRUE); break; case SB_PAGEUP: val = GetScrollPos (hwndScrollBar, SB_CTL); if (val > -127 + 10) val -= 10; else val = -127; SetScrollPos (hwndScrollBar, SB_CTL, val, TRUE); break; case SB_PAGEDOWN: val = GetScrollPos (hwndScrollBar, SB_CTL); if (val < 127 - 10) val += 10; else val = 127; SetScrollPos (hwndScrollBar, SB_CTL, val, TRUE); break; case SB_THUMBTRACK: val = nPos; SetScrollPos (hwndScrollBar, SB_CTL, val, TRUE); break; case SB_THUMBPOSITION: val = nPos; SetScrollPos (hwndScrollBar, SB_CTL, val, TRUE); break; } if (GetDlgItem (hDlg, IDC_SBSATURATION) == hwndScrollBar) { SetDlgItemInt (hDlg, IDC_EBSATURATION, (-val*100)/127, TRUE); data->saturation = (VPP_Char)(-val); } else if (GetDlgItem (hDlg, IDC_SBBRIGHTNESS) == hwndScrollBar) { SetDlgItemInt (hDlg, IDC_EBBRIGHTNESS, (-val*100)/127, TRUE); data->brightness = (VPP_Char)(-val); } else if (GetDlgItem (hDlg, IDC_SBCONTRAST) == hwndScrollBar) { SetDlgItemInt (hDlg, IDC_EBCONTRAST, (-val*100)/127, TRUE); data->contrast = (VPP_Char)(-val); } else if (GetDlgItem (hDlg, IDC_SBHUE) == hwndScrollBar) { SetDlgItemInt (hDlg, IDC_EBHUE, (-val*100)/127, TRUE); data->hue = (VPP_Char)(-val); } return val; } /****************************************************************************** ** Function name : inputFields ** Description : A function called when one of the input fields on the ** dialog box are activated or written in. Input fields are ** the fields one can write in. ** Parameters : hDld : Handle to the dialog box window. ** wID : The message used when scroll bars are used. ** generated by windows. ** data : the VPX_Config structure sent to the dialog ** box from the user. ** NOTE : Static function only used by the dialog box function. ******************************************************************************/ static void inputFields (HWND hDlg, WORD wID, VPX_Config VPP_far* data) { VPP_SnapData VPP_far *snapData; snapData = (data->videoStandard == VPP_PAL ? &data->snapDataPAL : &data->snapDataNTSC); switch (wID) { case IDC_EDX1: case IDC_EDY1: case IDC_EDX2: case IDC_EDY2: case IDC_EDWIDTH: case IDC_EDHEIGHT: snapData->xOffset = (VPP_Word) GetDlgItemInt (hDlg, IDC_EDX1, NULL, FALSE); snapData->yOffset = (VPP_Word) GetDlgItemInt (hDlg, IDC_EDY1, NULL, FALSE); snapData->xActive = (VPP_Word) GetDlgItemInt (hDlg, IDC_EDX2, NULL, FALSE); snapData->yActive = (VPP_Word) GetDlgItemInt (hDlg, IDC_EDY2, NULL, FALSE); snapData->xPixels = (VPP_Word) GetDlgItemInt (hDlg, IDC_EDWIDTH, NULL, FALSE); snapData->yPixels = (VPP_Word) GetDlgItemInt (hDlg, IDC_EDHEIGHT, NULL, FALSE); break; default : SetDlgItemInt (hDlg, IDC_EDX1, snapData->xOffset, FALSE); SetDlgItemInt (hDlg, IDC_EDY1, snapData->yOffset, FALSE); SetDlgItemInt (hDlg, IDC_EDX2, snapData->xActive, FALSE); SetDlgItemInt (hDlg, IDC_EDY2, snapData->yActive, FALSE); SetDlgItemInt (hDlg, IDC_EDWIDTH, snapData->xPixels, FALSE); SetDlgItemInt (hDlg, IDC_EDHEIGHT, snapData->yPixels, FALSE); break; } } /****************************************************************************** ** Function name : mouseMove ** Description : This function is called when the mouse is moved over ** the preview image and the left mouse button is pressed. ** This will set the VPP_SnapData structure so that the ** view inside the square on the preview image will be ** the same, as what is snapped with the VPP_SnapData. ** Parameters : hDlg : Handle to the dialog box window. ** first : This point structure contains the point where ** the mouse button was first pressed, this is used to ** support that the square is drawn any possible way on ** the preview image. ** lParam : Generated by windows, and contain a point, ** which is where the mouse cursor was when this message ** was sent. ** data : the VPX_Config structure sent to the dialog ** box from the user. ** NOTE : Static function only used by the dialog box function. ******************************************************************************/ static void mouseMove (HWND hDlg, POINT *first, LPARAM lParam, VPX_Config VPP_far *data) { VPP_LimitData limitData; double xFactor; double yFactor; POINT thisPoint; HWND hPreview; int x2,y2; RECT size; VPP_SnapData VPP_far *snapData; snapData = (data->videoStandard == VPP_PAL ? &data->snapDataPAL : &data->snapDataNTSC); VPP_getLimits (data->videoStandard, &limitData); #ifdef __WIN32__ POINTSTOPOINT(thisPoint,MAKEPOINTS(lParam)); #else thisPoint = MAKEPOINT (lParam); #endif hPreview = GetDlgItem (hDlg, IDC_PREVIEW); GetClientRect (hPreview, &size); MapWindowPoints (hDlg, hPreview, &thisPoint, 1); if ((thisPoint.x < 0 ) || (thisPoint.y < 0) || (thisPoint.x > size.right) || (thisPoint.y > size.bottom)) { return; } xFactor = ((float) limitData.xActiveMax /size.right); if (snapData->interlaced) { yFactor = ((float) limitData.yActiveMax /size.bottom); } else { yFactor = ((float) limitData.yActiveMax /size.bottom) / 2; } x2 = (int)((thisPoint.x - first->x) * xFactor); if (x2 >= 0) { snapData->xOffset = (int)(first->x * xFactor); snapData->xActive = x2 < 10 ? 10 : x2; } else { snapData->xOffset = (int)(thisPoint.x * xFactor); snapData->xActive = -x2 < 10 ? 10 : -x2; } y2 = (int)((thisPoint.y - first->y) * yFactor); if (y2 >= 0) { snapData->yOffset = (int)(first->y * yFactor); snapData->yActive = y2 < 10 ? 10 : y2; } else { snapData->yOffset = (int)(thisPoint.y * yFactor); snapData->yActive = -y2 < 10 ? 10 : -y2; } if (data->videoStandard == VPP_PAL) snapData->xPixels = (VPP_Word)((snapData->xActive*768L+920/2)/920); else snapData->xPixels = (VPP_Word)((snapData->xActive*640L+754/2)/754); if (snapData->interlaced == VPP_false) snapData->xPixels /= 2; snapData->yPixels = snapData->yActive; #ifdef VPP_NO_STRETCH_IMAGE if (snapData->xPixels > limitData.xPixelsMax) { snapData->yPixels = (VPP_Word)((long)snapData->yPixels* limitData.xPixelsMax/snapData->xPixels); snapData->xPixels = limitData.xPixelsMax; } if (snapData->yPixels > limitData.yPixelsMax) { snapData->xPixels = (VPP_Word)((long)snapData->xPixels* limitData.yPixelsMax/snapData->yPixels); snapData->yPixels = limitData.yPixelsMax; } #endif /* VPP_STRETCH_IMAGE */ VPX_prepare(data,VPP_false); inputFields(hDlg,0,data); } /****************************************************************************** ** Function name : lButtonDown ** Description : This function is called when the left mouse button is ** pressed and the dialog box gets the message. If the ** button is pressed on the preview image this will set ** the snapDdata offsets values. ** Parameters : hDlg : Handle to the dialog box window. ** first : This point structure contains the point where ** the mouse button was first pressed, this is used to ** support that the square is drawn any possible way on ** the preview image. ** lParam : Generated by windows, and contain a point, ** which is where the mouse cursor was when this message ** was sent. ** data : the VPX_Config structure sent to the dialog ** box from the user. ** NOTE : Static function only used by the dialog box function. ******************************************************************************/ static void lButtonDown (HWND hDlg, POINT *first, LPARAM lParam, VPX_Config VPP_far *data) { VPP_LimitData limitData; double xFactor; double yFactor; HWND hPreview; RECT size; VPP_SnapData VPP_far *snapData; snapData = (data->videoStandard == VPP_PAL ? &data->snapDataPAL : &data->snapDataNTSC); VPP_getLimits (data->videoStandard, &limitData); #ifdef __WIN32__ POINTSTOPOINT(*first,MAKEPOINTS(lParam)); #else *first = MAKEPOINT (lParam); #endif hPreview = GetDlgItem (hDlg, IDC_PREVIEW); MapWindowPoints (hDlg, hPreview, first, 1); GetClientRect (hPreview, &size); if ((first->x < 0 ) || (first->y < 0) || (first->x > size.right) || (first->y > size.bottom)) { first->x = -1; return; } xFactor = ((float) limitData.xActiveMax /size.right); if (snapData->interlaced) { yFactor = (float) limitData.yActiveMax /size.bottom; } else { yFactor = (float) limitData.yActiveMax /size.bottom / 2; } snapData->xOffset = (int)(first->x * xFactor); snapData->xActive = 10; snapData->xPixels = 10; snapData->yOffset = (int)(first->y * yFactor); snapData->yActive = 10; snapData->yPixels = 10; VPX_prepare(data,VPP_false); inputFields(hDlg,0,data); } #endif // end of DIALOG test.