📄 getframe.c
字号:
if (This->cbInBuffer >= readBytes)
break;
This->cbInBuffer = This->cbInFormat + readBytes;
This->lpInFormat = HeapReAlloc(GetProcessHeap(), 0, This->lpInFormat, This->cbInBuffer);
if (This->lpInFormat == NULL)
return NULL; /* out of memory */
This->lpInBuffer = (BYTE*)This->lpInFormat + This->cbInFormat;
}
if (readSamples != 1) {
ERR(": no frames read\n");
return NULL;
}
if (readBytes != 0) {
This->lpInFormat->biSizeImage = readBytes;
/* nothing to decompress? */
if (This->hic == NULL) {
This->lCurrentFrame = lPos;
return This->lpInFormat;
}
if (This->bResize) {
ICDecompressEx(This->hic,0,This->lpInFormat,This->lpInBuffer,0,0,
This->lpInFormat->biWidth,This->lpInFormat->biHeight,
This->lpOutFormat,This->lpOutBuffer,This->x,This->y,
This->dx,This->dy);
} else {
ICDecompress(This->hic, 0, This->lpInFormat, This->lpInBuffer,
This->lpOutFormat, This->lpOutBuffer);
}
}
} /* for (lNext < lPos) */
} /* if (This->lCurrentFrame != lPos) */
return (This->hic == NULL ? This->lpInFormat : This->lpOutFormat);
}
static HRESULT WINAPI IGetFrame_fnBegin(IGetFrame *iface, LONG lStart,
LONG lEnd, LONG lRate)
{
IGetFrameImpl *This = (IGetFrameImpl *)iface;
TRACE("(%p,%d,%d,%d)\n", iface, lStart, lEnd, lRate);
This->bFixedStream = TRUE;
return (IGetFrame_GetFrame(iface, lStart) ? AVIERR_OK : AVIERR_ERROR);
}
static HRESULT WINAPI IGetFrame_fnEnd(IGetFrame *iface)
{
IGetFrameImpl *This = (IGetFrameImpl *)iface;
TRACE("(%p)\n", iface);
This->bFixedStream = FALSE;
return AVIERR_OK;
}
static HRESULT WINAPI IGetFrame_fnSetFormat(IGetFrame *iface,
LPBITMAPINFOHEADER lpbiWanted,
LPVOID lpBits, INT x, INT y,
INT dx, INT dy)
{
IGetFrameImpl *This = (IGetFrameImpl *)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 ? TRUE : FALSE );
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) {
register 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;
}
}
/***********************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -