Exemple #1
0
int cap_ic_start(cap_cx *cx, char *err)
{
	char format[32];
	char message[80];

	if((cx->ic = ICDecompressOpen(
		ICTYPE_VIDEO,
		0,
		&(cx->pfmt->bmiHeader),
		NULL)))
	{
		cx->outfmtlen = ICDecompressGetFormatSize(cx->ic, cx->pfmt);
		if((cx->poutfmt = malloc(cx->outfmtlen)))
		{
			if(ICDecompressGetFormat(cx->ic, cx->pfmt, cx->poutfmt) == ICERR_OK)
			{
				if(ICDecompressBegin(cx->ic, cx->pfmt, cx->poutfmt) == ICERR_OK)
				{
					cx->mode = CAP_USE_IC;
					return 1;
				}
			}
			free(cx->poutfmt);
		}
		ICClose(cx->ic);
	}

	sprintf(message, "Can't open decompressor for format \"%s\"",
		reverse_fourcc(format, cx->pfmt->bmiHeader.biCompression));
	set_err(message);
	
	return 0;
}
Exemple #2
0
/* 对捕获的视频做编码、解码处理 */
void CMainFrame::OnVfwCodec()
{
	// TODO: 在此添加命令处理程序代码
	DWORD fsize;
	/* VCM initialization */
	hic1 = ICOpen(mmioFOURCC('v','i','d','c'),  mmioFOURCC('X','V','I','D'),  ICMODE_COMPRESS);
	if (hic1 == 0) 
		AfxMessageBox(_T("打开编码器失败!"));

	hic2 = ICOpen(mmioFOURCC('v','i','d','c'),  mmioFOURCC('X','V','I','D'),  ICMODE_DECOMPRESS);
	if (hic2 == 0) 
		AfxMessageBox(_T("打开解码器失败!"));

	fsize = capGetVideoFormatSize(m_hWndCap);
	capGetVideoFormat(m_hWndCap, lpbiIn, fsize);
	
	InitAVIWriteOpt();

	lpbiOut->bmiHeader.biSize          = sizeof(BITMAPINFOHEADER);
	lpbiOut->bmiHeader.biWidth         = lpbiIn->bmiHeader.biWidth;
	lpbiOut->bmiHeader.biHeight        = lpbiIn->bmiHeader.biHeight;
	lpbiOut->bmiHeader.biPlanes        = 1;
	lpbiOut->bmiHeader.biBitCount      = 24;
	lpbiOut->bmiHeader.biCompression   = BI_RGB;
	lpbiOut->bmiHeader.biSizeImage     = lpbiIn->bmiHeader.biWidth*lpbiIn->bmiHeader.biHeight*3;
	lpbiOut->bmiHeader.biXPelsPerMeter = 0;
	lpbiOut->bmiHeader.biYPelsPerMeter = 0;
	lpbiOut->bmiHeader.biClrUsed       = 0;
	lpbiOut->bmiHeader.biClrImportant  = 0;

//	get the format of the input video
	if (ICCompressGetFormat(hic1,lpbiIn,lpbiTmp)!=ICERR_OK) 
		AfxMessageBox(_T("编码器不能读取输出格式!"));
	if (ICCompressQuery(hic1,lpbiIn,lpbiTmp) != ICERR_OK)   
		AfxMessageBox(_T("不能处理编码器输入输出格式!"));

//	set the parameters of the CODEC
	pc.cbSize         = sizeof(COMPVARS);			//结构体大小
	pc.dwFlags        = ICMF_COMPVARS_VALID;
	pc.hic            = hic1;						//编码器句柄
	pc.fccType        = mmioFOURCC('v','i','d','c');
	pc.fccHandler     = mmioFOURCC('X','V','I','D');
	pc.lpbiOut        = lpbiTmp;					//输出格式
	pc.lKey           = 100;						//key帧频率
	pc.lQ             = 10000;						//图像质量

	if(!ICSeqCompressFrameStart(&pc, lpbiIn))
		return;
	ICDecompressBegin(hic2,lpbiTmp,lpbiOut);
	m_vfwState  = ENCDEC;
}
Exemple #3
0
static HRESULT AVIDec_ProcessBegin(TransformFilterImpl* pTransformFilter)
{
    AVIDecImpl* This = (AVIDecImpl*)pTransformFilter;
    DWORD result;

    TRACE("(%p)->()\n", This);

    result = ICDecompressBegin(This->hvid, This->pBihIn, This->pBihOut);
    if (result != ICERR_OK)
    {
        ERR("Cannot start processing (%d)\n", result);
	return E_FAIL;
    }
    return S_OK;
}
Exemple #4
0
static HRESULT WINAPI AVIDec_StartStreaming(TransformFilter* pTransformFilter)
{
    AVIDecImpl* This = impl_from_TransformFilter(pTransformFilter);
    DWORD result;

    TRACE("(%p)->()\n", This);
    This->late = -1;

    result = ICDecompressBegin(This->hvid, This->pBihIn, This->pBihOut);
    if (result != ICERR_OK)
    {
        ERR("Cannot start processing (%d)\n", result);
	return E_FAIL;
    }
    return S_OK;
}
Exemple #5
0
IplImage* CvCaptureCAM_VFW::retrieveFrame(int)
{
    BITMAPINFO vfmt;
    memset( &vfmt, 0, sizeof(vfmt));
    BITMAPINFOHEADER& vfmt0 = vfmt.bmiHeader;

    if( !capWnd )
        return 0;

    const DWORD sz = capGetVideoFormat( capWnd, &vfmt, sizeof(vfmt));
    const int prevWidth = frame ? frame->width : 0;
    const int prevHeight = frame ? frame->height : 0;

    if( !hdr || hdr->lpData == 0 || sz == 0 )
        return 0;

    if( !frame || frame->width != vfmt0.biWidth || frame->height != vfmt0.biHeight )
    {
        cvReleaseImage( &frame );
        frame = cvCreateImage( cvSize( vfmt0.biWidth, vfmt0.biHeight ), 8, 3 );
    }

    if ( vfmt0.biCompression == MAKEFOURCC('N','V','1','2') )
    {
        // Frame is in YUV 4:2:0 NV12 format, convert to BGR color space
        // See https://msdn.microsoft.com/en-us/library/windows/desktop/dd206750(v=vs.85).aspx#nv12)
        IplImage src;
        cvInitImageHeader( &src, cvSize( vfmt0.biWidth, vfmt0.biHeight * 3 / 2 ), IPL_DEPTH_8U, 1, IPL_ORIGIN_BL, 4 );
        cvSetData( &src, hdr->lpData, src.widthStep );
        cvCvtColor( &src, frame, CV_YUV2BGR_NV12 );
    }
    else if( vfmt0.biCompression != BI_RGB ||
             vfmt0.biBitCount != 24 )
    {
        BITMAPINFOHEADER vfmt1 = icvBitmapHeader( vfmt0.biWidth, vfmt0.biHeight, 24 );

        if( hic == 0 || fourcc != vfmt0.biCompression ||
            prevWidth != vfmt0.biWidth || prevHeight != vfmt0.biHeight )
        {
            closeHIC();
            hic = ICOpen( MAKEFOURCC('V','I','D','C'),
                          vfmt0.biCompression, ICMODE_DECOMPRESS );
            if( hic )
            {
                if( ICDecompressBegin( hic, &vfmt0, &vfmt1 ) != ICERR_OK )
                {
                    closeHIC();
                    return 0;
                }
            }
        }

        if( !hic || ICDecompress( hic, 0, &vfmt0, hdr->lpData,
            &vfmt1, frame->imageData ) != ICERR_OK )
        {
            closeHIC();
            return 0;
        }

        cvFlip( frame, frame, 0 );
    }
    else
    {
        IplImage src;
        cvInitImageHeader( &src, cvSize(vfmt0.biWidth, vfmt0.biHeight),
            IPL_DEPTH_8U, 3, IPL_ORIGIN_BL, 4 );
        cvSetData( &src, hdr->lpData, src.widthStep );
        cvFlip( &src, frame, 0 );
    }

    return frame;
}
Exemple #6
0
/***********************************************************************
 *              DrawDibBegin            [MSVFW32.@]
 */
BOOL VFWAPI DrawDibBegin(HDRAWDIB hdd,
                         HDC      hdc,
                         INT      dxDst,
                         INT      dyDst,
                         LPBITMAPINFOHEADER lpbi,
                         INT      dxSrc,
                         INT      dySrc,
                         UINT     wFlags) 
{
    BOOL ret = TRUE;
    WINE_HDD *whdd;

    TRACE("(%p,%p,%d,%d,%p,%d,%d,0x%08x)\n",
          hdd, hdc, dxDst, dyDst, lpbi, dxSrc, dySrc, wFlags);

    TRACE("lpbi: %d,%d/%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
          lpbi->biSize, lpbi->biWidth, lpbi->biHeight, lpbi->biPlanes,
          lpbi->biBitCount, lpbi->biCompression, lpbi->biSizeImage,
          lpbi->biXPelsPerMeter, lpbi->biYPelsPerMeter, lpbi->biClrUsed,
          lpbi->biClrImportant);

    if (wFlags & ~(DDF_BUFFER))
        FIXME("wFlags == 0x%08x not handled\n", wFlags & ~(DDF_BUFFER));

    whdd = MSVIDEO_GetHddPtr(hdd);
    if (!whdd) return FALSE;

    if (whdd->begun) DrawDibEnd(hdd);

    if (lpbi->biCompression) 
    {
        DWORD size = 0;

        whdd->hic = ICOpen(ICTYPE_VIDEO, lpbi->biCompression, ICMODE_DECOMPRESS);
        if (!whdd->hic) 
        {
            WARN("Could not open IC. biCompression == 0x%08x\n", lpbi->biCompression);
            ret = FALSE;
        }

        if (ret) 
        {
            size = ICDecompressGetFormat(whdd->hic, lpbi, NULL);
            if (size == ICERR_UNSUPPORTED) 
            {
                WARN("Codec doesn't support GetFormat, giving up.\n");
                ret = FALSE;
            }
        }

        if (ret) 
        {
            whdd->lpbiOut = HeapAlloc(GetProcessHeap(), 0, size);

            if (ICDecompressGetFormat(whdd->hic, lpbi, whdd->lpbiOut) != ICERR_OK)
                ret = FALSE;
        }

        if (ret) 
        {
            /* FIXME: Use Ex functions if available? */
            if (ICDecompressBegin(whdd->hic, lpbi, whdd->lpbiOut) != ICERR_OK)
                ret = FALSE;
            
            TRACE("biSizeImage == %d\n", whdd->lpbiOut->biSizeImage);
            TRACE("biCompression == %d\n", whdd->lpbiOut->biCompression);
            TRACE("biBitCount == %d\n", whdd->lpbiOut->biBitCount);
        }
    }
    else 
    {
        DWORD dwSize;
        /* No compression */
        TRACE("Not compressed!\n");
        if (lpbi->biHeight <= 0)
        {
            /* we don't draw inverted DIBs */
            TRACE("detected inverted DIB\n");
            ret = FALSE;
        }
        else
        {
            dwSize = lpbi->biSize + num_colours(lpbi)*sizeof(RGBQUAD);
            whdd->lpbiOut = HeapAlloc(GetProcessHeap(), 0, dwSize);
            memcpy(whdd->lpbiOut, lpbi, dwSize);
        }
    }

    if (ret) 
    {
        /*whdd->lpvbuf = HeapAlloc(GetProcessHeap(), 0, whdd->lpbiOut->biSizeImage);*/

        whdd->hMemDC = CreateCompatibleDC(hdc);
        TRACE("Creating: %d, %p\n", whdd->lpbiOut->biSize, whdd->lpvbits);
        whdd->hDib = CreateDIBSection(whdd->hMemDC, (BITMAPINFO *)whdd->lpbiOut, DIB_RGB_COLORS, &(whdd->lpvbits), 0, 0);
        if (whdd->hDib) 
        {
            TRACE("Created: %p,%p\n", whdd->hDib, whdd->lpvbits);
        }
        else
        {
            ret = FALSE;
            TRACE("Error: %d\n", GetLastError());
        }
        whdd->hOldDib = SelectObject(whdd->hMemDC, whdd->hDib);
    }

    if (ret) 
    {
        whdd->hdc = hdc;
        whdd->dxDst = dxDst;
        whdd->dyDst = dyDst;
        whdd->lpbi = HeapAlloc(GetProcessHeap(), 0, lpbi->biSize);
        memcpy(whdd->lpbi, lpbi, lpbi->biSize);
        whdd->dxSrc = dxSrc;
        whdd->dySrc = dySrc;
        whdd->begun = TRUE;
        whdd->hpal = 0;
    } 
    else 
    {
        if (whdd->hic)
            ICClose(whdd->hic);
        HeapFree(GetProcessHeap(), 0, whdd->lpbiOut);
        whdd->lpbiOut = NULL;
    }

    return ret;
}
Exemple #7
0
// init driver
static int init(sh_video_t *sh){
    HRESULT ret;
//    unsigned int outfmt=sh->codec->outfmt[sh->outfmtidx];
    int i, o_bih_len;
    vd_vfw_ctx *priv;
    const char *dll = codec_idx2str(sh->codec->dll_idx);

    /* Hack for VSSH codec: new dll can't decode old files
     * In my samples old files have no extradata, so use that info
     * to decide what dll should be used (here and in vd_dshow).
     */
    if (!strcmp(dll, "vssh264.dll") && (sh->bih->biSize > 40))
      return 0;

    priv = malloc(sizeof(vd_vfw_ctx));
    if (!priv)
	return 0;
    memset(priv, 0, sizeof(vd_vfw_ctx));
    sh->context = priv;

    mp_msg(MSGT_WIN32,MSGL_V,"======= Win32 (VFW) VIDEO Codec init =======\n");


//    win32_codec_name = dll;
//    sh->hic = ICOpen( 0x63646976, sh->bih->biCompression, ICMODE_FASTDECOMPRESS);
//    priv->handle = ICOpen( 0x63646976, sh->bih->biCompression, ICMODE_DECOMPRESS);
    priv->handle = ICOpen( (long)(dll), sh->bih->biCompression, ICMODE_DECOMPRESS);
    if(!priv->handle){
	mp_msg(MSGT_WIN32,MSGL_ERR,"ICOpen failed! unknown codec / wrong parameters?\n");
	return 0;
    }

//    sh->bih->biBitCount=32;

    o_bih_len = ICDecompressGetFormatSize(priv->handle, sh->bih);

    if(o_bih_len < sizeof(BITMAPINFOHEADER)){
       mp_msg(MSGT_WIN32,MSGL_ERR,"ICDecompressGetFormatSize returned a bogus value: %d\n", o_bih_len);
       return 0;
    }

    priv->o_bih = malloc(o_bih_len);
    memset(priv->o_bih, 0, o_bih_len);

    mp_msg(MSGT_WIN32,MSGL_V,"ICDecompressGetFormatSize ret: %d\n", o_bih_len);

    ret = ICDecompressGetFormat(priv->handle, sh->bih, priv->o_bih);
    if(ret < 0){
	mp_msg(MSGT_WIN32,MSGL_ERR,"ICDecompressGetFormat failed: Error %d\n", (int)ret);
	for (i=0; i < o_bih_len; i++) mp_msg(MSGT_WIN32, MSGL_DBG2, "%02x ", priv->o_bih[i]);
	return 0;
    }
    mp_msg(MSGT_WIN32,MSGL_V,"ICDecompressGetFormat OK\n");

#if 0
    // workaround for pegasus MJPEG:
    if(!sh_video->o_bih.biWidth) sh_video->o_bih.biWidth=sh_video->bih->biWidth;
    if(!sh_video->o_bih.biHeight) sh_video->o_bih.biHeight=sh_video->bih->biHeight;
    if(!sh_video->o_bih.biPlanes) sh_video->o_bih.biPlanes=sh_video->bih->biPlanes;
#endif

    // ok let libvo and vd core to handshake and decide the optimal csp:
    if(!mpcodecs_config_vo(sh,sh->disp_w,sh->disp_h,IMGFMT_YUY2)) return 0;

    if (!(sh->codec->outflags[sh->outfmtidx]&CODECS_FLAG_FLIP)) {
	priv->o_bih->biHeight=-sh->bih->biHeight; // flip image!
    }

    // ok, let's set the choosen colorspace:
    set_csp(priv->o_bih,sh->codec->outfmt[sh->outfmtidx]);

    // fake it to RGB for broken DLLs (divx3)
    if(sh->codec->outflags[sh->outfmtidx] & CODECS_FLAG_YUVHACK)
	priv->o_bih->biCompression = 0;

    // sanity check:
#ifdef BUILD_VFWEX
    ret = ICDecompressQueryEx(priv->handle, sh->bih, priv->o_bih);
#else
    ret = ICDecompressQuery(priv->handle, sh->bih, priv->o_bih);
#endif
    if (ret)
    {
	mp_msg(MSGT_WIN32,MSGL_WARN,"ICDecompressQuery failed: Error %d\n", (int)ret);
//	return 0;
    } else
	mp_msg(MSGT_WIN32,MSGL_V,"ICDecompressQuery OK\n");

#ifdef BUILD_VFWEX
    ret = ICDecompressBeginEx(priv->handle, sh->bih, priv->o_bih);
#else
    ret = ICDecompressBegin(priv->handle, sh->bih, priv->o_bih);
#endif
    if (ret)
    {
	mp_msg(MSGT_WIN32,MSGL_WARN,"ICDecompressBegin failed: Error %d\n", (int)ret);
//	return 0;
    }

    // for broken codecs set it again:
    if(sh->codec->outflags[sh->outfmtidx] & CODECS_FLAG_YUVHACK)
	set_csp(priv->o_bih,sh->codec->outfmt[sh->outfmtidx]);

    mp_msg(MSGT_WIN32, MSGL_V, "Input format:\n");
    if( mp_msg_test(MSGT_HEADER,MSGL_V) ) print_video_header(sh->bih,MSGL_V);
    mp_msg(MSGT_WIN32, MSGL_V, "Output format:\n");
    if( mp_msg_test(MSGT_HEADER,MSGL_V) ) print_video_header(priv->o_bih,MSGL_V);

    // set postprocessing level in xvid/divx4 .dll
    ICSendMessage(priv->handle, ICM_USER+80, (long)(&divx_quality), 0);

    // don't do this palette mess always, it makes div3 dll crashing...
    if(sh->codec->outfmt[sh->outfmtidx]==IMGFMT_BGR8){
	if(ICDecompressGetPalette(priv->handle, sh->bih, priv->o_bih)){
	    priv->palette = (unsigned char*)(priv->o_bih+1);
	    mp_msg(MSGT_WIN32,MSGL_V,"ICDecompressGetPalette OK\n");
	} else {
	    if(sh->bih->biSize>=40+4*4)
		priv->palette = (unsigned char*)(sh->bih+1);
	}
    }

    mp_msg(MSGT_DECVIDEO,MSGL_V,"INFO: Win32 video codec init OK!\n");
    return 1;
}
Exemple #8
0
static LBXGL_VidCodecCTX *vfw_begin_decompress(int fcc,
	PDGL_BMPInfoHeader *in, PDGL_BMPInfoHeader *out)
{
	LBXGL_VidCodecCTX *ctx;
	vfw_ctxinfo *info;
	int err;

	ctx=LBXGL_VidCodecCTX_New();
	info=gcalloc(sizeof(vfw_ctxinfo));
	ctx->data=info;

	info->ihead=malloc(sizeof(BITMAPINFOHEADER));
	memset(info->ihead, 0, sizeof(BITMAPINFOHEADER));
	info->ihead->biSize		= sizeof(BITMAPINFOHEADER);
	info->ihead->biWidth		= in->biWidth;
	info->ihead->biHeight		= in->biHeight;
	info->ihead->biPlanes		= in->biPlanes;
	info->ihead->biBitCount		= in->biBitCount;
	info->ihead->biCompression	= in->biCompression;
	info->ihead->biSizeImage	=
		in->biWidth*in->biHeight*in->biBitCount/8;

	info->ohead=malloc(sizeof(BITMAPINFOHEADER));
	memset(info->ohead, 0, sizeof(BITMAPINFOHEADER));
	info->ohead->biSize		= sizeof(BITMAPINFOHEADER);
	info->ohead->biWidth		= out->biWidth;
//	info->ohead->biHeight		= -out->biHeight;
	info->ohead->biHeight		= out->biHeight;
	info->ohead->biPlanes		= out->biPlanes;
	info->ohead->biBitCount		= out->biBitCount;
	info->ohead->biCompression	= out->biCompression;
	info->ihead->biSizeImage	=
		out->biWidth*out->biHeight*out->biBitCount/8;

	info->buffer=malloc(out->biWidth*out->biHeight*out->biBitCount/8);

//	info->hicd = ICOpen(ICTYPE_VIDEO, fcc, ICMODE_FASTDECOMPRESS);
	info->hicd = ICLocate(ICTYPE_VIDEO, fcc,
		info->ihead, info->ohead, ICMODE_FASTDECOMPRESS);
	if(!info->hicd)
	{
		printf("VFW: decompress %0.4s %0.4s: fail\n",
			&fcc, &in->biCompression);
		return(NULL);
	}
	printf("VFW: decompress %0.4s %0.4s: ok\n", &fcc, &in->biCompression);


	err=ICDecompressBegin(info->hicd, info->ihead, info->ohead);
	if(err)
	{
		printf("VFW: err %d, %0.4s %0.4s: fail\n", err,
			&fcc, &in->biCompression);
		return(NULL);
	}

	vfw_hicd[vfw_n_hicd++]=info->hicd;

	ctx->decompress_frame=&vfw_decompress_frame;

	return(ctx);
}
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;
}
Exemple #10
0
static HRESULT WINAPI IGetFrame_fnSetFormat(IGetFrame *iface,
					    LPBITMAPINFOHEADER lpbiWanted,
					    LPVOID lpBits, INT x, INT y,
					    INT dx, INT dy)
{
  IGetFrameImpl *This = impl_from_IGetFrame(iface);

  AVISTREAMINFOW     sInfo;
  LPBITMAPINFOHEADER lpbi         = lpbiWanted;
  BOOL               bBestDisplay = FALSE;

  TRACE("(%p,%p,%p,%d,%d,%d,%d)\n", iface, lpbiWanted, lpBits,
	x, y, dx, dy);

  if (This->pStream == NULL)
    return AVIERR_ERROR;

  if (lpbiWanted == (LPBITMAPINFOHEADER)AVIGETFRAMEF_BESTDISPLAYFMT) {
    lpbi = NULL;
    bBestDisplay = TRUE;
  }

  IAVIStream_Info(This->pStream, &sInfo, sizeof(sInfo));
  if (sInfo.fccType != streamtypeVIDEO)
    return AVIERR_UNSUPPORTED;

  This->bFormatChanges = (sInfo.dwFlags & AVISTREAMINFO_FORMATCHANGES) != 0;
  This->dwFormatChangeCount = sInfo.dwFormatChangeCount;
  This->dwEditCount         = sInfo.dwEditCount;
  This->lCurrentFrame       = -1;

  /* get input format from stream */
  if (This->lpInFormat == NULL) {
    HRESULT hr;

    This->cbInBuffer = (LONG)sInfo.dwSuggestedBufferSize;
    if (This->cbInBuffer == 0)
      This->cbInBuffer = 1024;

    IAVIStream_ReadFormat(This->pStream, sInfo.dwStart,
			  NULL, &This->cbInFormat);

    This->lpInFormat = HeapAlloc(GetProcessHeap(), 0, This->cbInFormat + This->cbInBuffer);
    if (This->lpInFormat == NULL) {
      AVIFILE_CloseCompressor(This);
      return AVIERR_MEMORY;
    }

    hr = IAVIStream_ReadFormat(This->pStream, sInfo.dwStart, This->lpInFormat, &This->cbInFormat);
    if (FAILED(hr)) {
      AVIFILE_CloseCompressor(This);
      return hr;
    }

    This->lpInBuffer = ((LPBYTE)This->lpInFormat) + This->cbInFormat;
  }

  /* check input format */
  if (This->lpInFormat->biClrUsed == 0 && This->lpInFormat->biBitCount <= 8)
    This->lpInFormat->biClrUsed = 1u << This->lpInFormat->biBitCount;
  if (This->lpInFormat->biSizeImage == 0 &&
      This->lpInFormat->biCompression == BI_RGB) {
    This->lpInFormat->biSizeImage =
      DIBWIDTHBYTES(*This->lpInFormat) * This->lpInFormat->biHeight;
  }

  /* only to pass through? */
  if (This->lpInFormat->biCompression == BI_RGB && lpBits == NULL) {
    if (lpbi == NULL || 
	(lpbi->biCompression == BI_RGB &&
	 lpbi->biWidth == This->lpInFormat->biWidth &&
	 lpbi->biHeight == This->lpInFormat->biHeight &&
	 lpbi->biBitCount == This->lpInFormat->biBitCount)) {
      This->lpOutFormat = This->lpInFormat;
      This->lpOutBuffer = DIBPTR(This->lpInFormat);
      return AVIERR_OK;
    }
  }

  /* need memory for output format? */
  if (This->lpOutFormat == NULL) {
    This->lpOutFormat =
      HeapAlloc(GetProcessHeap(), 0, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
    if (This->lpOutFormat == NULL) {
      AVIFILE_CloseCompressor(This);
      return AVIERR_MEMORY;
    }
  }

  /* need handle to video compressor */
  if (This->hic == NULL) {
    FOURCC fccHandler;

    if (This->lpInFormat->biCompression == BI_RGB)
      fccHandler = comptypeDIB;
    else if (This->lpInFormat->biCompression == BI_RLE8)
      fccHandler = mmioFOURCC('R','L','E',' ');
    else
      fccHandler = sInfo.fccHandler;

    if (lpbi != NULL) {
      if (lpbi->biWidth == 0)
	lpbi->biWidth = This->lpInFormat->biWidth;
      if (lpbi->biHeight == 0)
	lpbi->biHeight = This->lpInFormat->biHeight;
    }

    This->hic = ICLocate(ICTYPE_VIDEO, fccHandler, This->lpInFormat, lpbi, ICMODE_DECOMPRESS);
    if (This->hic == NULL) {
      AVIFILE_CloseCompressor(This);
      return AVIERR_NOCOMPRESSOR;
    }
  }

  /* output format given? */
  if (lpbi != NULL) {
    /* check the given output format ... */
    if (lpbi->biClrUsed == 0 && lpbi->biBitCount <= 8)
      lpbi->biClrUsed = 1u << lpbi->biBitCount;

    /* ... and remember it */
    memcpy(This->lpOutFormat, lpbi,
	   lpbi->biSize + lpbi->biClrUsed * sizeof(RGBQUAD));
    if (lpbi->biBitCount <= 8)
      ICDecompressGetPalette(This->hic, This->lpInFormat, This->lpOutFormat);

    return AVIERR_OK;
  } else {
    if (bBestDisplay) {
      ICGetDisplayFormat(This->hic, This->lpInFormat,
			 This->lpOutFormat, 0, dx, dy);
    } else if (ICDecompressGetFormat(This->hic, This->lpInFormat,
				     This->lpOutFormat) < 0) {
      AVIFILE_CloseCompressor(This);
      return AVIERR_NOCOMPRESSOR;
    }

    /* check output format */
    if (This->lpOutFormat->biClrUsed == 0 &&
	This->lpOutFormat->biBitCount <= 8)
      This->lpOutFormat->biClrUsed = 1u << This->lpOutFormat->biBitCount;
    if (This->lpOutFormat->biSizeImage == 0 &&
	This->lpOutFormat->biCompression == BI_RGB) {
      This->lpOutFormat->biSizeImage =
	DIBWIDTHBYTES(*This->lpOutFormat) * This->lpOutFormat->biHeight;
    }

    if (lpBits == NULL) {
      DWORD size = This->lpOutFormat->biClrUsed * sizeof(RGBQUAD);

      size += This->lpOutFormat->biSize + This->lpOutFormat->biSizeImage;
      This->lpOutFormat = HeapReAlloc(GetProcessHeap(), 0, This->lpOutFormat, size);
      if (This->lpOutFormat == NULL) {
	AVIFILE_CloseCompressor(This);
	return AVIERR_MEMORY;
      }
      This->lpOutBuffer = DIBPTR(This->lpOutFormat);
    } else
      This->lpOutBuffer = lpBits;

    /* for user size was irrelevant */
    if (dx == -1)
      dx = This->lpOutFormat->biWidth;
    if (dy == -1)
      dy = This->lpOutFormat->biHeight;

    /* need to resize? */
    if (x != 0 || y != 0) {
      if (dy == This->lpOutFormat->biHeight &&
	  dx == This->lpOutFormat->biWidth)
	This->bResize = FALSE;
      else
	This->bResize = TRUE;
    }

    if (This->bResize) {
      This->x  = x;
      This->y  = y;
      This->dx = dx;
      This->dy = dy;

      if (ICDecompressExBegin(This->hic,0,This->lpInFormat,This->lpInBuffer,0,
			      0,This->lpInFormat->biWidth,
			      This->lpInFormat->biHeight,This->lpOutFormat,
			      This->lpOutBuffer, x, y, dx, dy) == ICERR_OK)
	return AVIERR_OK;
    } else if (ICDecompressBegin(This->hic, This->lpInFormat,
				 This->lpOutFormat) == ICERR_OK)
      return AVIERR_OK;

    AVIFILE_CloseCompressor(This);

    return AVIERR_COMPRESSOR;
  }
}
Exemple #11
0
IplImage* CvCaptureCAM_VFW::retrieveFrame(int)
{
    BITMAPINFO vfmt;
    memset( &vfmt, 0, sizeof(vfmt));
    BITMAPINFOHEADER& vfmt0 = vfmt.bmiHeader;

    if( !capWnd )
        return 0;

    const DWORD sz = capGetVideoFormat( capWnd, &vfmt, sizeof(vfmt));
    const int prevWidth = frame ? frame->width : 0;
    const int prevHeight = frame ? frame->height : 0;

    if( !hdr || hdr->lpData == 0 || sz == 0 )
        return 0;

    if( !frame || frame->width != vfmt0.biWidth || frame->height != vfmt0.biHeight )
    {
        cvReleaseImage( &frame );
        frame = cvCreateImage( cvSize( vfmt0.biWidth, vfmt0.biHeight ), 8, 3 );
    }

    if( vfmt0.biCompression != BI_RGB ||
        vfmt0.biBitCount != 24 )
    {
        BITMAPINFOHEADER vfmt1 = icvBitmapHeader( vfmt0.biWidth, vfmt0.biHeight, 24 );

        if( hic == 0 || fourcc != vfmt0.biCompression ||
            prevWidth != vfmt0.biWidth || prevHeight != vfmt0.biHeight )
        {
            closeHIC();
            hic = ICOpen( MAKEFOURCC('V','I','D','C'),
                          vfmt0.biCompression, ICMODE_DECOMPRESS );
            if( hic )
            {
                if( ICDecompressBegin( hic, &vfmt0, &vfmt1 ) != ICERR_OK )
                {
                    closeHIC();
                    return 0;
                }
            }
        }

        if( !hic || ICDecompress( hic, 0, &vfmt0, hdr->lpData,
            &vfmt1, frame->imageData ) != ICERR_OK )
        {
            closeHIC();
            return 0;
        }

        cvFlip( frame, frame, 0 );
    }
    else
    {
        IplImage src;
        cvInitImageHeader( &src, cvSize(vfmt0.biWidth, vfmt0.biHeight),
            IPL_DEPTH_8U, 3, IPL_ORIGIN_BL, 4 );
        cvSetData( &src, hdr->lpData, src.widthStep );
        cvFlip( &src, frame, 0 );
    }

    return frame;
}
Exemple #12
0
HANDLE VFWAPI ICImageDecompress(
	HIC hic, UINT uiFlags, LPBITMAPINFO lpbiIn,
	LPVOID lpBits, LPBITMAPINFO lpbiOut)
{
	HGLOBAL	hMem = NULL;
	BYTE*	pMem = NULL;
	BOOL	bReleaseIC = FALSE;
	BYTE*	pHdr = NULL;
	ULONG	cbHdr = 0;
	BOOL	bSucceeded = FALSE;
	BOOL	bInDecompress = FALSE;
	DWORD	biSizeImage;

	TRACE("(%p,%08x,%p,%p,%p)\n",
		hic, uiFlags, lpbiIn, lpBits, lpbiOut);

	if ( hic == NULL )
	{
		hic = ICDecompressOpen( ICTYPE_VIDEO, 0, &lpbiIn->bmiHeader, (lpbiOut != NULL) ? &lpbiOut->bmiHeader : NULL );
		if ( hic == NULL )
		{
			WARN("no handler\n" );
			goto err;
		}
		bReleaseIC = TRUE;
	}
	if ( uiFlags != 0 )
	{
		FIXME( "unknown flag %08x\n", uiFlags );
		goto err;
	}
	if ( lpbiIn == NULL || lpBits == NULL )
	{
		WARN("invalid argument\n");
		goto err;
	}

	if ( lpbiOut != NULL )
	{
		if ( lpbiOut->bmiHeader.biSize != sizeof(BITMAPINFOHEADER) )
			goto err;
		cbHdr = sizeof(BITMAPINFOHEADER);
		if ( lpbiOut->bmiHeader.biCompression == 3 )
			cbHdr += sizeof(DWORD)*3;
		else
		if ( lpbiOut->bmiHeader.biBitCount <= 8 )
		{
			if ( lpbiOut->bmiHeader.biClrUsed == 0 )
				cbHdr += sizeof(RGBQUAD) * (1<<lpbiOut->bmiHeader.biBitCount);
			else
				cbHdr += sizeof(RGBQUAD) * lpbiOut->bmiHeader.biClrUsed;
		}
	}
	else
	{
		TRACE( "get format\n" );

		cbHdr = ICDecompressGetFormatSize(hic,lpbiIn);
		if ( cbHdr < sizeof(BITMAPINFOHEADER) )
			goto err;
		pHdr = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,cbHdr+sizeof(RGBQUAD)*256);
		if ( pHdr == NULL )
			goto err;
		if ( ICDecompressGetFormat( hic, lpbiIn, pHdr ) != ICERR_OK )
			goto err;
		lpbiOut = (BITMAPINFO*)pHdr;
		if ( lpbiOut->bmiHeader.biBitCount <= 8 &&
			 ICDecompressGetPalette( hic, lpbiIn, lpbiOut ) != ICERR_OK &&
			 lpbiIn->bmiHeader.biBitCount == lpbiOut->bmiHeader.biBitCount )
		{
			if ( lpbiIn->bmiHeader.biClrUsed == 0 )
				memcpy( lpbiOut->bmiColors, lpbiIn->bmiColors, sizeof(RGBQUAD)*(1<<lpbiOut->bmiHeader.biBitCount) );
			else
				memcpy( lpbiOut->bmiColors, lpbiIn->bmiColors, sizeof(RGBQUAD)*lpbiIn->bmiHeader.biClrUsed );
		}
		if ( lpbiOut->bmiHeader.biBitCount <= 8 &&
			 lpbiOut->bmiHeader.biClrUsed == 0 )
			lpbiOut->bmiHeader.biClrUsed = 1<<lpbiOut->bmiHeader.biBitCount;

		lpbiOut->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
		cbHdr = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*lpbiOut->bmiHeader.biClrUsed;
	}

	biSizeImage = lpbiOut->bmiHeader.biSizeImage;
	if ( biSizeImage == 0 )
		biSizeImage = ((((lpbiOut->bmiHeader.biWidth * lpbiOut->bmiHeader.biBitCount + 7) >> 3) + 3) & (~3)) * abs(lpbiOut->bmiHeader.biHeight);

	TRACE( "call ICDecompressBegin\n" );

	if ( ICDecompressBegin( hic, lpbiIn, lpbiOut ) != ICERR_OK )
		goto err;
	bInDecompress = TRUE;

	TRACE( "cbHdr %d, biSizeImage %d\n", cbHdr, biSizeImage );

	hMem = GlobalAlloc( GMEM_MOVEABLE|GMEM_ZEROINIT, cbHdr + biSizeImage );
	if ( hMem == NULL )
	{
		WARN( "out of memory\n" );
		goto err;
	}
	pMem = GlobalLock( hMem );
	if ( pMem == NULL )
		goto err;
	memcpy( pMem, lpbiOut, cbHdr );

	TRACE( "call ICDecompress\n" );
	if ( ICDecompress( hic, 0, &lpbiIn->bmiHeader, lpBits, &lpbiOut->bmiHeader, pMem+cbHdr ) != ICERR_OK )
		goto err;

	bSucceeded = TRUE;
err:
	if ( bInDecompress )
		ICDecompressEnd( hic );
	if ( bReleaseIC )
		ICClose(hic);
        HeapFree(GetProcessHeap(),0,pHdr);
	if ( pMem != NULL )
		GlobalUnlock( hMem );
	if ( !bSucceeded && hMem != NULL )
	{
		GlobalFree(hMem); hMem = NULL;
	}

	return hMem;
}
BOOST_DATA_TEST_CASE(vcm_encdec, make_data_from_tuple_container(vecEncDecClips), src, dst, fmt, config, tolerance)
{
	VideoClip srcClip(src);
	VideoClip dstClip(dst);
	DWORD fccCodec = FCC(fmt);

	BOOST_REQUIRE(srcClip.GetWidth() == dstClip.GetWidth());
	BOOST_REQUIRE(srcClip.GetHeight() == dstClip.GetHeight());

	DWORD fccSrc = srcClip.GetFourCC();
	DWORD fccDst = dstClip.GetFourCC();
	unsigned int nWidth = srcClip.GetWidth();
	unsigned int nHeight = srcClip.GetHeight();

	size_t cbSrcData;
	size_t cbDstData;
	size_t cbCompressedData;

	HIC hicEncode, hicDecode;
	LRESULT lr;
	union
	{
		BITMAPINFOHEADER bihCompressed;
		char bihCompressedBuf[128];
	};
	BITMAPINFOHEADER bihSrc;
	BITMAPINFOHEADER bihDst;

	hicEncode = ICOpen(ICTYPE_VIDEO, fccCodec, ICMODE_COMPRESS);
	BOOST_REQUIRE(hicEncode != NULL);
	ICCloser iccloserEnc(hicEncode);

	lr = ICSetState(hicEncode, &config.front(), config.size());
	BOOST_REQUIRE(lr == config.size());

	hicDecode = ICOpen(ICTYPE_VIDEO, fccCodec, ICMODE_DECOMPRESS);
	BOOST_REQUIRE(hicDecode != NULL);
	ICCloser iccloserDec(hicDecode);

	memset(&bihSrc, 0, sizeof(BITMAPINFOHEADER));
	bihSrc.biSize = sizeof(BITMAPINFOHEADER);
	bihSrc.biWidth = nWidth;
	bihSrc.biHeight = nHeight;
	bihSrc.biPlanes = 1;
	bihSrc.biBitCount = FCC2BitCount(fccSrc);
	bihSrc.biCompression = FCC2Compression(fccSrc);
	bihSrc.biSizeImage = 10000000;

	memset(&bihDst, 0, sizeof(BITMAPINFOHEADER));
	bihDst.biSize = sizeof(BITMAPINFOHEADER);
	bihDst.biWidth = nWidth;
	bihDst.biHeight = nHeight;
	bihDst.biPlanes = 1;
	bihDst.biBitCount = FCC2BitCount(fccDst);
	bihDst.biCompression = FCC2Compression(fccDst);
	bihDst.biSizeImage = 10000000;

	lr = ICCompressGetFormat(hicEncode, &bihSrc, &bihCompressed);
	BOOST_REQUIRE_EQUAL(lr, ICERR_OK);
	cbCompressedData = ICCompressGetSize(hicEncode, &bihSrc, &bihCompressed);

	lr = ICCompressBegin(hicEncode, &bihSrc, &bihCompressed);
	BOOST_REQUIRE_EQUAL(lr, ICERR_OK);

	lr = ICDecompressBegin(hicDecode, &bihCompressed, &bihDst);
	BOOST_REQUIRE_EQUAL(lr, ICERR_OK);

	void *pSrcData;
	void *pDstData;
	void *pEncoderOut = malloc(cbCompressedData);
	void *pDecoderOut = NULL;
	int retSrc, retDst;
	LONG lFrameNum = 0;
	while ((retSrc = srcClip.GetNextFrame(&pSrcData, &cbSrcData, NULL)) == 0 &&
		(retDst = dstClip.GetNextFrame(&pDstData, &cbDstData, NULL) == 0))
	{
		DWORD dwFlags = 0;
		lr = ICCompress(hicEncode, 0, &bihCompressed, pEncoderOut, &bihSrc, pSrcData, NULL, &dwFlags, lFrameNum++, 0, 0, &bihSrc, NULL);
		BOOST_REQUIRE(lr == ICERR_OK);

		if (pDecoderOut == NULL)
			pDecoderOut = malloc(cbDstData);

		lr = ICDecompress(hicDecode, (dwFlags & AVIIF_KEYFRAME) ? 0 : ICDECOMPRESS_NOTKEYFRAME, &bihCompressed, pEncoderOut, &bihDst, pDecoderOut);
		BOOST_REQUIRE(lr == ICERR_OK);

		BOOST_CHECK(bihDst.biSizeImage == cbDstData);
		BOOST_CHECK(CompareFrame(pDstData, pDecoderOut, nWidth, cbDstData, fccDst, tolerance) == 0);
	}

	BOOST_CHECK(retSrc != 0 && retDst != 0);
	if (pDecoderOut != NULL)
		free(pDecoderOut);
	free(pEncoderOut);

	lr = ICDecompressEnd(hicDecode);
	BOOST_CHECK(lr == ICERR_OK);

	lr = ICCompressEnd(hicEncode);
	BOOST_CHECK(lr == ICERR_OK);
}
Exemple #14
0
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;
}
Exemple #15
0
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);
}