static HRESULT fill_format_info(AVICompressor *This, VIDEOINFOHEADER *src_videoinfo) { DWORD size; ICINFO icinfo; HRESULT hres; hres = ensure_driver(This); if(hres != S_OK) return hres; size = ICGetInfo(This->hic, &icinfo, sizeof(icinfo)); if(size != sizeof(icinfo)) return E_FAIL; size = ICCompressGetFormatSize(This->hic, &src_videoinfo->bmiHeader); if(!size) { FIXME("ICCompressGetFormatSize failed\n"); return E_FAIL; } size += FIELD_OFFSET(VIDEOINFOHEADER, bmiHeader); This->videoinfo = heap_alloc(size); if(!This->videoinfo) return E_OUTOFMEMORY; This->videoinfo_size = size; This->driver_flags = icinfo.dwFlags; memset(This->videoinfo, 0, sizeof(*This->videoinfo)); ICCompressGetFormat(This->hic, &src_videoinfo->bmiHeader, &This->videoinfo->bmiHeader); This->videoinfo->dwBitRate = 10000000/src_videoinfo->AvgTimePerFrame * This->videoinfo->bmiHeader.biSizeImage * 8; This->videoinfo->AvgTimePerFrame = src_videoinfo->AvgTimePerFrame; This->max_frame_size = This->videoinfo->bmiHeader.biSizeImage; return S_OK; }
std::shared_ptr<WatermarkSearchResult> WatermarkSearchWorker::findWatermark(int width, int height) { std::shared_ptr<WatermarkSearchResult> r = std::make_shared<WatermarkSearchResult>(); r->size_.width_ = width; r->size_.height_ = height; int const bytesPerPixel = 4; int const scanlineSizeInBytes = width * bytesPerPixel; BITMAPINFOHEADER inputFormat; ZeroMemory(&inputFormat, sizeof(inputFormat)); inputFormat.biSize = sizeof(inputFormat); inputFormat.biWidth = width; inputFormat.biHeight = height; inputFormat.biPlanes = 1; inputFormat.biBitCount = 8 * bytesPerPixel; inputFormat.biCompression = BI_RGB; inputFormat.biSizeImage = scanlineSizeInBytes * height; DWORD const size = ICCompressGetFormatSize(compressor_, &inputFormat); if (size == 0 || (size & 0xFFFF0000) == 0xFFFF0000) { return r; } std::vector<uint8_t> outputFormatStorage(size); LPBITMAPINFOHEADER outputFormat = (LPBITMAPINFOHEADER)(BITMAPINFO*)outputFormatStorage.data(); if (ICCompressGetFormat(compressor_, &inputFormat, outputFormat) != ICERR_OK) { return r; } DWORD const outputSize = ICCompressGetSize(compressor_, &inputFormat, outputFormat); if (outputSize < 0) { return r; } if (outputBuffer_.size() < outputSize) { outputBuffer_.resize(outputSize); } if (inputBuffer_.size() < inputFormat.biSizeImage) { inputBuffer_.resize(inputFormat.biSizeImage); } std::fill(inputBuffer_.begin(), inputBuffer_.begin() + inputFormat.biSizeImage, (uint8_t)0xff); if (ICCompressBegin(compressor_, &inputFormat, outputFormat) != ICERR_OK) { return r; } DWORD flags = 0; DWORD dwckid = 0; DWORD result = ICCompress(compressor_, 0, // dwFlags outputFormat, outputBuffer_.data(), &inputFormat, inputBuffer_.data(), &dwckid, &flags, 0, // lpFrameNum 0, // dwFrameSize 0, // dwQuality nullptr, // lpbiPrev nullptr); // lpPrev if (result != ICERR_OK) { return r; } if (ICCompressEnd(compressor_) != ICERR_OK) { return r; } if (ICDecompressBegin(decompressor_, outputFormat, &inputFormat) != ICERR_OK) { return r; } std::fill(inputBuffer_.begin(), inputBuffer_.begin() + inputFormat.biSizeImage, (uint8_t)0xff); if (ICDecompress(decompressor_, 0, outputFormat, outputBuffer_.data(), &inputFormat, inputBuffer_.data()) != ICERR_OK) { return r; } if (ICDecompressEnd(decompressor_) != ICERR_OK) { return r; } // Search left edge of watermark int left = -1; for (int x = 0; x < width; ++x) { bool found = false; for (int y = 0; y < height; ++y) { for (int j = 0; j < bytesPerPixel; ++j) { int index = scanlineSizeInBytes * y + x * bytesPerPixel + j; if (inputBuffer_[index] != (uint8_t)0xff) { found = true; left = x; break; } } if (found) { break; } } if (found) { break; } } if (left < 0) { return r; } // Search right edge of watermark int right = -1; for (int x = width - 1; x >= 0; --x) { bool found = false; for (int y = 0; y < height; ++y) { for (int j = 0; j < bytesPerPixel; ++j) { int index = scanlineSizeInBytes * y + x * bytesPerPixel + j; if (inputBuffer_[index] != (uint8_t)0xff) { found = true; right = x; break; } } if (found) { break; } } if (found) { break; } } if (right < 0) { return r; } // Search top edge of watermark int top = -1; for (int y = 0; y < height; ++y) { bool found = false; for (int x = 0; x < width; ++x) { for (int j = 0; j < bytesPerPixel; ++j) { int index = scanlineSizeInBytes * y + x * bytesPerPixel + j; if (inputBuffer_[index] != (uint8_t)0xff) { found = true; top = y; break; } } if (found) { break; } } if (found) { break; } } if (top < 0) { return r; } // Search bottom edge of watermark int bottom = -1; for (int y = height - 1; y >= 0; --y) { bool found = false; for (int x = 0; x < width; ++x) { for (int j = 0; j < bytesPerPixel; ++j) { int index = scanlineSizeInBytes * y + x * bytesPerPixel + j; if (inputBuffer_[index] != (uint8_t)0xff) { found = true; bottom = y; break; } } if (found) { break; } } if (found) { break; } } if (top < 0) { return r; } r->x_ = left; r->y_ = top; int const watermarkWidth = right - left + 1; int const watermarkHeight = bottom - top + 1; r->width_ = watermarkWidth; r->height_ = watermarkHeight; r->watermark_ = std::make_shared<Bitmap>(watermarkWidth, watermarkHeight); for (int y = 0; y < watermarkHeight; ++y) { for (int x = 0; x < watermarkWidth; ++x) { int index = scanlineSizeInBytes * (y + top) + (x + left) * bytesPerPixel; uint8_t red = inputBuffer_[index]; uint8_t green = inputBuffer_[index + 1]; uint8_t blue = inputBuffer_[index + 2]; r->watermark_->setPixel(x, watermarkHeight - y - 1, Color{ red, green, blue }); } } return r; }
//int init_vfw_encoder(char *dll_name, BITMAPINFOHEADER *input_bih, BITMAPINFOHEADER *output_bih) static BITMAPINFOHEADER* vfw_open_encoder(char *dll_name, char *compdatafile, BITMAPINFOHEADER *input_bih,unsigned int out_fourcc) { HRESULT ret; BITMAPINFOHEADER* output_bih=NULL; int temp_len; FILE *fd=NULL; char *drvdata=NULL; struct stat st; //sh_video = malloc(sizeof(sh_video_t)); mp_msg(MSGT_WIN32,MSGL_V,"======= Win32 (VFW) VIDEO Encoder init =======\n"); CoInitRes = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); // memset(&sh_video->o_bih, 0, sizeof(BITMAPINFOHEADER)); // output_bih->biSize = sizeof(BITMAPINFOHEADER); // encoder_hic = ICOpen( 0x63646976, out_fourcc, ICMODE_COMPRESS); encoder_hic = ICOpen( (long) dll_name, out_fourcc, ICMODE_COMPRESS); if(!encoder_hic){ mp_msg(MSGT_WIN32,MSGL_ERR,"ICOpen failed! unknown codec / wrong parameters?\n"); return NULL; } mp_msg(MSGT_WIN32,MSGL_INFO,"HIC: %x\n", encoder_hic); #if 1 { ICINFO icinfo; ret = ICGetInfo(encoder_hic, &icinfo, sizeof(ICINFO)); mp_msg(MSGT_WIN32,MSGL_INFO,"%ld - %ld - %d\n", ret, icinfo.dwSize, sizeof(ICINFO)); mp_msg(MSGT_WIN32,MSGL_INFO,MSGTR_MPCODECS_CompressorType, icinfo.fccType); mp_msg(MSGT_WIN32,MSGL_INFO,MSGTR_MPCODECS_CompressorSubtype, icinfo.fccHandler); mp_msg(MSGT_WIN32,MSGL_INFO,MSGTR_MPCODECS_CompressorFlags, icinfo.dwFlags, icinfo.dwVersion, icinfo.dwVersionICM); //printf("Compressor name: %s\n", icinfo.szName); //printf("Compressor description: %s\n", icinfo.szDescription); mp_msg(MSGT_WIN32,MSGL_INFO,MSGTR_MPCODECS_Flags); if (icinfo.dwFlags & VIDCF_QUALITY) mp_msg(MSGT_WIN32,MSGL_INFO,MSGTR_MPCODECS_Quality); if (icinfo.dwFlags & VIDCF_FASTTEMPORALD) mp_msg(MSGT_WIN32,MSGL_INFO," fast-decompr"); if (icinfo.dwFlags & VIDCF_QUALITYTIME) mp_msg(MSGT_WIN32,MSGL_INFO," temp-quality"); mp_msg(MSGT_WIN32,MSGL_INFO,"\n"); } #endif if(compdatafile){ if (!strncmp(compdatafile, "dialog", 6)){ if (ICSendMessage(encoder_hic, ICM_CONFIGURE, -1, 0) != ICERR_OK){ mp_msg(MSGT_WIN32,MSGL_ERR,"Compressor doesn't have a configure dialog!\n"); return NULL; } if (ICSendMessage(encoder_hic, ICM_CONFIGURE, 0, 0) != ICERR_OK){ mp_msg(MSGT_WIN32,MSGL_ERR,"Compressor configure dialog failed!\n"); return NULL; } } else { if (stat(compdatafile, &st) < 0){ mp_msg(MSGT_WIN32,MSGL_ERR,"Compressor data file not found!\n"); return NULL; } fd = fopen(compdatafile, "rb"); if (!fd){ mp_msg(MSGT_WIN32,MSGL_ERR,"Cannot open Compressor data file!\n"); return NULL; } drvdata = (char *) malloc(st.st_size); if (fread(drvdata, st.st_size, 1, fd) != 1) { mp_msg(MSGT_WIN32,MSGL_ERR,"Cannot read Compressor data file!\n"); fclose(fd); free(drvdata); return NULL; } fclose(fd); mp_msg(MSGT_WIN32,MSGL_ERR,"Compressor data %d bytes\n", st.st_size); if (!(temp_len = (unsigned int) ICSendMessage(encoder_hic, ICM_SETSTATE, (LPARAM) drvdata, (int) st.st_size))){ mp_msg(MSGT_WIN32,MSGL_ERR,"ICSetState failed!\n"); free(drvdata); return NULL; } free(drvdata); mp_msg(MSGT_WIN32,MSGL_INFO,"ICSetState ret: %d\n", temp_len); } } temp_len = ICCompressGetFormatSize(encoder_hic, input_bih); mp_msg(MSGT_WIN32,MSGL_INFO,"ICCompressGetFormatSize ret: %d\n", temp_len); if (temp_len < sizeof(BITMAPINFOHEADER)) temp_len=sizeof(BITMAPINFOHEADER); output_bih = malloc(temp_len+4); memset(output_bih,0,temp_len); output_bih->biSize = temp_len; //sizeof(BITMAPINFOHEADER); return output_bih; }
static HRESULT AVIFILE_OpenGetFrame(IAVIStreamImpl *This) { LPBITMAPINFOHEADER lpbi; DWORD size; /* pre-conditions */ assert(This != NULL); assert(This->pStream != NULL); assert(This->pg == NULL); This->pg = AVIStreamGetFrameOpen(This->pStream, NULL); if (This->pg == NULL) return AVIERR_ERROR; /* When we only decompress this is enough */ if (This->sInfo.fccHandler == comptypeDIB) return AVIERR_OK; assert(This->hic != NULL); assert(This->lpbiOutput == NULL); /* get input format */ lpbi = AVIStreamGetFrame(This->pg, This->sInfo.dwStart); if (lpbi == NULL) return AVIERR_MEMORY; /* get memory for output format */ size = ICCompressGetFormatSize(This->hic, lpbi); if ((LONG)size < (LONG)sizeof(BITMAPINFOHEADER)) return AVIERR_COMPRESSOR; This->lpbiOutput = HeapAlloc(GetProcessHeap(), 0, size); if (This->lpbiOutput == NULL) return AVIERR_MEMORY; This->cbOutput = size; if (ICCompressGetFormat(This->hic, lpbi, This->lpbiOutput) < S_OK) return AVIERR_BADFORMAT; /* update AVISTREAMINFO structure */ This->sInfo.rcFrame.right = This->sInfo.rcFrame.left + This->lpbiOutput->biWidth; This->sInfo.rcFrame.bottom = This->sInfo.rcFrame.top + This->lpbiOutput->biHeight; This->sInfo.dwSuggestedBufferSize = ICCompressGetSize(This->hic, lpbi, This->lpbiOutput); /* prepare codec for compression */ if (ICCompressBegin(This->hic, lpbi, This->lpbiOutput) != S_OK) return AVIERR_COMPRESSOR; /* allocate memory for current frame */ size += This->sInfo.dwSuggestedBufferSize; This->lpbiCur = HeapAlloc(GetProcessHeap(), 0, size); if (This->lpbiCur == NULL) return AVIERR_MEMORY; memcpy(This->lpbiCur, This->lpbiOutput, This->cbOutput); This->lpCur = DIBPTR(This->lpbiCur); /* allocate memory for last frame if needed */ if (This->lKeyFrameEvery != 1 && (This->dwICMFlags & VIDCF_FASTTEMPORALC) == 0) { size = ICDecompressGetFormatSize(This->hic, This->lpbiOutput); This->lpbiPrev = HeapAlloc(GetProcessHeap(), 0, size); if (This->lpbiPrev == NULL) return AVIERR_MEMORY; if (ICDecompressGetFormat(This->hic, This->lpbiOutput, This->lpbiPrev) < S_OK) return AVIERR_COMPRESSOR; if (This->lpbiPrev->biSizeImage == 0) { This->lpbiPrev->biSizeImage = DIBWIDTHBYTES(*This->lpbiPrev) * This->lpbiPrev->biHeight; } /* get memory for format and picture */ size += This->lpbiPrev->biSizeImage; This->lpbiPrev = HeapReAlloc(GetProcessHeap(), 0, This->lpbiPrev, size ); if (This->lpbiPrev == NULL) return AVIERR_MEMORY; This->lpPrev = DIBPTR(This->lpbiPrev); /* prepare codec also for decompression */ if (ICDecompressBegin(This->hic,This->lpbiOutput,This->lpbiPrev) != S_OK) return AVIERR_COMPRESSOR; } return AVIERR_OK; }
static HRESULT WINAPI ICMStream_fnSetFormat(IAVIStream *iface, LONG pos, LPVOID format, LONG formatsize) { IAVIStreamImpl *This = impl_from_IAVIStream(iface); TRACE("(%p,%d,%p,%d)\n", iface, pos, format, formatsize); /* check parameters */ if (format == NULL || formatsize <= 0) return AVIERR_BADPARAM; /* We can only accept RGB data for writing */ if (((LPBITMAPINFOHEADER)format)->biCompression != BI_RGB) { WARN(": need RGB data as input\n"); return AVIERR_UNSUPPORTED; } /* Input format already known? * Changing of palette is supported, but be quiet if it's the same */ if (This->lpbiInput != NULL) { if (This->cbInput != formatsize) return AVIERR_UNSUPPORTED; if (memcmp(format, This->lpbiInput, formatsize) == 0) return AVIERR_OK; } /* Does the nested stream support writing? */ if ((This->sInfo.dwCaps & AVIFILECAPS_CANWRITE) == 0) return AVIERR_READONLY; /* check if frame is already written */ if (This->sInfo.dwLength + This->sInfo.dwStart > pos) return AVIERR_UNSUPPORTED; /* check if we should compress */ if (This->sInfo.fccHandler == 0 || This->sInfo.fccHandler == mmioFOURCC('N','O','N','E')) This->sInfo.fccHandler = comptypeDIB; /* only pass through? */ if (This->sInfo.fccHandler == comptypeDIB) return IAVIStream_SetFormat(This->pStream, pos, format, formatsize); /* initial format setting? */ if (This->lpbiInput == NULL) { ULONG size; assert(This->hic != NULL); /* get memory for input format */ This->lpbiInput = HeapAlloc(GetProcessHeap(), 0, formatsize); if (This->lpbiInput == NULL) return AVIERR_MEMORY; This->cbInput = formatsize; memcpy(This->lpbiInput, format, formatsize); /* get output format */ size = ICCompressGetFormatSize(This->hic, This->lpbiInput); if (size < sizeof(BITMAPINFOHEADER)) return AVIERR_COMPRESSOR; This->lpbiOutput = HeapAlloc(GetProcessHeap(), 0, size); if (This->lpbiOutput == NULL) return AVIERR_MEMORY; This->cbOutput = size; if (ICCompressGetFormat(This->hic,This->lpbiInput,This->lpbiOutput) < S_OK) return AVIERR_COMPRESSOR; /* update AVISTREAMINFO structure */ This->sInfo.rcFrame.right = This->sInfo.rcFrame.left + This->lpbiOutput->biWidth; This->sInfo.rcFrame.bottom = This->sInfo.rcFrame.top + This->lpbiOutput->biHeight; /* prepare codec for compression */ if (ICCompressBegin(This->hic, This->lpbiInput, This->lpbiOutput) != S_OK) return AVIERR_COMPRESSOR; /* allocate memory for compressed frame */ size = ICCompressGetSize(This->hic, This->lpbiInput, This->lpbiOutput); This->lpbiCur = HeapAlloc(GetProcessHeap(), 0, This->cbOutput + size); if (This->lpbiCur == NULL) return AVIERR_MEMORY; memcpy(This->lpbiCur, This->lpbiOutput, This->cbOutput); This->lpCur = DIBPTR(This->lpbiCur); /* allocate memory for last frame if needed */ if (This->lKeyFrameEvery != 1 && (This->dwICMFlags & VIDCF_FASTTEMPORALC) == 0) { size = ICDecompressGetFormatSize(This->hic, This->lpbiOutput); This->lpbiPrev = HeapAlloc(GetProcessHeap(), 0, size); if (This->lpbiPrev == NULL) return AVIERR_MEMORY; if (ICDecompressGetFormat(This->hic, This->lpbiOutput, This->lpbiPrev) < S_OK) return AVIERR_COMPRESSOR; if (This->lpbiPrev->biSizeImage == 0) { This->lpbiPrev->biSizeImage = DIBWIDTHBYTES(*This->lpbiPrev) * This->lpbiPrev->biHeight; } /* get memory for format and picture */ size += This->lpbiPrev->biSizeImage; This->lpbiPrev = HeapReAlloc(GetProcessHeap(), 0, This->lpbiPrev, size); if (This->lpbiPrev == NULL) return AVIERR_MEMORY; This->lpPrev = DIBPTR(This->lpbiPrev); /* prepare codec also for decompression */ if (ICDecompressBegin(This->hic,This->lpbiOutput,This->lpbiPrev) != S_OK) return AVIERR_COMPRESSOR; } } else { /* format change -- check that's only the palette */ LPBITMAPINFOHEADER lpbi = format; if (lpbi->biSize != This->lpbiInput->biSize || lpbi->biWidth != This->lpbiInput->biWidth || lpbi->biHeight != This->lpbiInput->biHeight || lpbi->biBitCount != This->lpbiInput->biBitCount || lpbi->biPlanes != This->lpbiInput->biPlanes || lpbi->biCompression != This->lpbiInput->biCompression || lpbi->biClrUsed != This->lpbiInput->biClrUsed) return AVIERR_UNSUPPORTED; /* get new output format */ if (ICCompressGetFormat(This->hic, lpbi, This->lpbiOutput) < S_OK) return AVIERR_BADFORMAT; /* restart compression */ ICCompressEnd(This->hic); if (ICCompressBegin(This->hic, lpbi, This->lpbiOutput) != S_OK) return AVIERR_COMPRESSOR; /* check if we need to restart decompression also */ if (This->lKeyFrameEvery != 1 && (This->dwICMFlags & VIDCF_FASTTEMPORALC) == 0) { ICDecompressEnd(This->hic); if (ICDecompressGetFormat(This->hic,This->lpbiOutput,This->lpbiPrev) < S_OK) return AVIERR_COMPRESSOR; if (ICDecompressBegin(This->hic,This->lpbiOutput,This->lpbiPrev) != S_OK) return AVIERR_COMPRESSOR; } } /* tell nested stream the new format */ return IAVIStream_SetFormat(This->pStream, pos, This->lpbiOutput, This->cbOutput); }
long __stdcall DlgProc ( HWND hWnd , unsigned msg , unsigned wParam , long lParam ) { switch(msg) { case WM_INITDIALOG: //hEdit = GetDlgItem( hWnd , I_EDIT ); //GetClientRect( hEdit , &rect ); hWndCap = capCreateCaptureWindow ( NULL, WS_CHILD | WS_VISIBLE , 0, 0, 320, 240, hWnd, 1235 ); //hWndCap = capCreateCaptureWindow ( NULL, WS_CHILD | WS_VISIBLE , 0, 0, (rect.right-rect.left ), (rect.bottom-rect.top), hEdit, 1235); // вручную заполняем структуру CapVar ZeroMemory( &CapVar, sizeof(COMPVARS) ); CapVar.cbSize = sizeof(COMPVARS); CapVar.dwFlags = ICMF_COMPVARS_VALID; CapVar.cbState = 0; CapVar.fccHandler = mmioFOURCC( 'x', '2', '6', '4' ); CapVar.fccType = ICTYPE_VIDEO; // открываем декомпрессор (долго) CapVar.hic = ICOpen( ICTYPE_VIDEO, CapVar.fccHandler, ICMODE_COMPRESS ); hThread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)SendThread, NULL, 0, 0 ); return -1 ; case WM_COMMAND: switch(LOWORD(wParam)) { case I_BUTTON_CONN : if( !capDriverConnect( hWndCap, 0 ) ) { EndDialog ( hWnd, 0 ); return -1; } capCaptureGetSetup( hWndCap, &CapParms, sizeof(CAPTUREPARMS) ); CapParms.dwRequestMicroSecPerFrame = 66000; CapParms.fLimitEnabled = FALSE; CapParms.fCaptureAudio = FALSE; CapParms.fMCIControl = FALSE; CapParms.fYield = TRUE; CapParms.vKeyAbort = VK_ESCAPE; CapParms.fAbortLeftMouse = FALSE; CapParms.fAbortRightMouse = FALSE; capCaptureSetSetup( hWndCap, &CapParms, sizeof(CAPTUREPARMS) ); capPreviewScale( hWndCap, 1 ); capPreviewRate( hWndCap, 66 ); capPreviewScale( hWndCap, FALSE ); capPreview( hWndCap, 1 ); //added by jimmy // OPTIONAL STEP: Setup resolution capGetVideoFormat( hWndCap, &InputBmpInfo ,sizeof(InputBmpInfo) ); //InputBmpInfo.bmiHeader.biWidth = 320; //(rect.right-rect.left ); //InputBmpInfo.bmiHeader.biHeight = 240; //(rect.bottom-rect.top); //InputBmpInfo.bmiHeader.biBitCount = 24; capSetVideoFormat( hWndCap, &InputBmpInfo, sizeof(InputBmpInfo) ); //capDriverDisconnect (hWndCap, 0);//Can we do better? //capDriverConnect (hWndCap, 0); capSetCallbackOnFrame( hWndCap, FrameCallBack ); if(CapVar.hic > 0 ) { OutFormatSize = ICCompressGetFormatSize( CapVar.hic, &InputBmpInfo.bmiHeader ); // BITMAPINFO возвращает размер структуры исходных данных InputBmpInfo ICCompressGetFormat( CapVar.hic, &InputBmpInfo.bmiHeader, &OutputBmpInfo.bmiHeader ); // заполняет структуру получаемых данных OutputBmpInfo OutBufferSize = ICCompressGetSize( CapVar.hic, &InputBmpInfo.bmiHeader, &OutputBmpInfo.bmiHeader ); // максимальный размер одного сжатого кадра (полученного) ICSeqCompressFrameStart( &CapVar, &InputBmpInfo ); // начало сжатия } break; case I_BUTTON_EXIT : ICSeqCompressFrameEnd(&CapVar); // конец сжатия ICCompressorFree(&CapVar); ICClose(CapVar.hic); capPreview( hWndCap , false ); capDriverDisconnect( hWndCap ); EndDialog ( hWnd , 0 ) ; break; } return -1 ; case WM_CLOSE : ICSeqCompressFrameEnd(&CapVar); // конец сжатия ICCompressorFree(&CapVar); ICClose(CapVar.hic); capPreview( hWndCap , false ); capDriverDisconnect( hWndCap ); EndDialog ( hWnd , 0 ) ; return -1 ; } return 0 ; }