Add video for windows control for zmbv codec
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2458
This commit is contained in:
parent
952f8f0d1d
commit
5190334069
1 changed files with 334 additions and 0 deletions
334
src/libs/zmbv/zmbv_vfw.cpp
Normal file
334
src/libs/zmbv/zmbv_vfw.cpp
Normal file
|
@ -0,0 +1,334 @@
|
|||
/*
|
||||
* Copyright (C) 2002-2005 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
//
|
||||
// Zipped Motion Block Video
|
||||
//
|
||||
// Based on Huffyuv by Ben Rudiak-Gould.
|
||||
// which was based on MSYUV sample code, which is:
|
||||
// Copyright (c) 1993 Microsoft Corporation.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
|
||||
#include "zmbv_vfw.h"
|
||||
#include "resource.h"
|
||||
|
||||
#include <crtdbg.h>
|
||||
#include <string.h>
|
||||
|
||||
TCHAR szDescription[] = TEXT("Zipped Motion Block Video v0.1");
|
||||
TCHAR szName[] = TEXT(CODEC_4CC);
|
||||
|
||||
#define VERSION 0x00000001 // 0.1
|
||||
|
||||
/********************************************************************
|
||||
********************************************************************/
|
||||
|
||||
CodecInst *encode_table_owner, *decode_table_owner;
|
||||
|
||||
/********************************************************************
|
||||
********************************************************************/
|
||||
|
||||
void Msg(const char fmt[], ...) {
|
||||
DWORD written;
|
||||
char buf[2000];
|
||||
va_list val;
|
||||
|
||||
va_start(val, fmt);
|
||||
wvsprintf(buf, fmt, val);
|
||||
|
||||
const COORD _80x50 = {80,50};
|
||||
static BOOL startup = (AllocConsole(), SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), _80x50));
|
||||
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), buf, lstrlen(buf), &written, 0);
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
********************************************************************/
|
||||
|
||||
CodecInst::CodecInst() {
|
||||
codec = 0;
|
||||
}
|
||||
|
||||
CodecInst* Open(ICOPEN* icinfo) {
|
||||
if (icinfo && icinfo->fccType != ICTYPE_VIDEO)
|
||||
return NULL;
|
||||
|
||||
CodecInst* pinst = new CodecInst();
|
||||
|
||||
if (icinfo) icinfo->dwError = pinst ? ICERR_OK : ICERR_MEMORY;
|
||||
|
||||
return pinst;
|
||||
}
|
||||
|
||||
DWORD Close(CodecInst* pinst) {
|
||||
// delete pinst; // this caused problems when deleting at app close time
|
||||
return 1;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
********************************************************************/
|
||||
|
||||
|
||||
/********************************************************************
|
||||
********************************************************************/
|
||||
|
||||
BOOL CodecInst::QueryAbout() { return TRUE; }
|
||||
|
||||
static BOOL CALLBACK AboutDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
||||
if (uMsg == WM_COMMAND) {
|
||||
switch (LOWORD(wParam)) {
|
||||
case IDOK:
|
||||
EndDialog(hwndDlg, 0);
|
||||
break;
|
||||
case IDC_HOMEPAGE:
|
||||
ShellExecute(NULL, NULL, "http://dosbox.sf.net", NULL, NULL, SW_SHOW);
|
||||
break;
|
||||
case IDC_EMAIL:
|
||||
ShellExecute(NULL, NULL, "mailto:db.crew@gmail.com", NULL, NULL, SW_SHOW);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
DWORD CodecInst::About(HWND hwnd) {
|
||||
DialogBox(hmoduleCodec, MAKEINTRESOURCE(IDD_ABOUT), hwnd, AboutDialogProc);
|
||||
return ICERR_OK;
|
||||
}
|
||||
|
||||
static BOOL CALLBACK ConfigureDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
||||
|
||||
if (uMsg == WM_INITDIALOG) {
|
||||
|
||||
} else if (uMsg == WM_COMMAND) {
|
||||
|
||||
switch (LOWORD(wParam)) {
|
||||
|
||||
case IDOK:
|
||||
|
||||
case IDCANCEL:
|
||||
EndDialog(hwndDlg, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
return AboutDialogProc(hwndDlg, uMsg, wParam, lParam); // handle email and home-page buttons
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CodecInst::QueryConfigure() { return TRUE; }
|
||||
|
||||
DWORD CodecInst::Configure(HWND hwnd) {
|
||||
DialogBox(hmoduleCodec, MAKEINTRESOURCE(IDD_CONFIGURE), hwnd, ConfigureDialogProc);
|
||||
return ICERR_OK;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
********************************************************************/
|
||||
|
||||
|
||||
// we have no state information which needs to be stored
|
||||
|
||||
DWORD CodecInst::GetState(LPVOID pv, DWORD dwSize) { return 0; }
|
||||
|
||||
DWORD CodecInst::SetState(LPVOID pv, DWORD dwSize) { return 0; }
|
||||
|
||||
|
||||
DWORD CodecInst::GetInfo(ICINFO* icinfo, DWORD dwSize) {
|
||||
if (icinfo == NULL)
|
||||
return sizeof(ICINFO);
|
||||
|
||||
if (dwSize < sizeof(ICINFO))
|
||||
return 0;
|
||||
|
||||
icinfo->dwSize = sizeof(ICINFO);
|
||||
icinfo->fccType = ICTYPE_VIDEO;
|
||||
memcpy(&icinfo->fccHandler,CODEC_4CC, 4);
|
||||
icinfo->dwFlags = VIDCF_FASTTEMPORALC | VIDCF_FASTTEMPORALD | VIDCF_TEMPORAL | VIDCF_QUALITY;
|
||||
|
||||
icinfo->dwVersion = VERSION;
|
||||
icinfo->dwVersionICM = ICVERSION;
|
||||
MultiByteToWideChar(CP_ACP, 0, szDescription, -1, icinfo->szDescription, sizeof(icinfo->szDescription)/sizeof(WCHAR));
|
||||
MultiByteToWideChar(CP_ACP, 0, szName, -1, icinfo->szName, sizeof(icinfo->szName)/sizeof(WCHAR));
|
||||
|
||||
return sizeof(ICINFO);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
****************************************************************/
|
||||
|
||||
static bool CanCompress(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut) {
|
||||
if (lpbiIn) {
|
||||
if (lpbiIn->biCompression) return false;
|
||||
if (lpbiIn->biBitCount==24) return false;
|
||||
} else return false;
|
||||
if (lpbiOut) {
|
||||
if (memcmp(&lpbiOut->biCompression,CODEC_4CC, 4))
|
||||
return false;
|
||||
} else return false;
|
||||
return true;
|
||||
}
|
||||
/********************************************************************
|
||||
****************************************************************/
|
||||
|
||||
DWORD CodecInst::CompressQuery(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut) {
|
||||
if (CanCompress(lpbiIn,lpbiOut)) return ICERR_OK;
|
||||
return ICERR_BADFORMAT;
|
||||
}
|
||||
|
||||
DWORD CodecInst::CompressGetFormat(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut) {
|
||||
if (!lpbiOut)
|
||||
return sizeof(BITMAPINFOHEADER);
|
||||
if (!CanCompress(lpbiIn,lpbiOut))
|
||||
return ICERR_BADFORMAT;
|
||||
return ICERR_OK;
|
||||
}
|
||||
|
||||
DWORD CodecInst::CompressBegin(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut) {
|
||||
CompressEnd(); // free resources if necessary
|
||||
if (!CanCompress(lpbiIn, lpbiOut))
|
||||
return ICERR_BADFORMAT;
|
||||
codec = new VideoCodec();
|
||||
if (!codec)
|
||||
return ICERR_MEMORY;
|
||||
if (!codec->SetupCompress( lpbiIn->biWidth, lpbiIn->biHeight))
|
||||
return ICERR_MEMORY;
|
||||
return ICERR_OK;
|
||||
}
|
||||
|
||||
DWORD CodecInst::CompressGetSize(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut) {
|
||||
if (!CanCompress(lpbiIn, lpbiOut))
|
||||
return ICERR_BADFORMAT;
|
||||
return lpbiIn->biWidth * lpbiIn->biHeight * lpbiIn->biBitCount/8 + 1024;
|
||||
}
|
||||
|
||||
DWORD CodecInst::Compress(ICCOMPRESS* icinfo, DWORD dwSize) {
|
||||
int i, pitch;
|
||||
zmbv_format_t format;
|
||||
LPBITMAPINFOHEADER lpbiIn=icinfo->lpbiInput;
|
||||
LPBITMAPINFOHEADER lpbiOut=icinfo->lpbiOutput;
|
||||
if (!CanCompress(lpbiIn, lpbiOut))
|
||||
return ICERR_BADFORMAT;
|
||||
if (!icinfo->lpInput || !icinfo->lpOutput)
|
||||
return ICERR_ABORT;
|
||||
switch (lpbiIn->biBitCount) {
|
||||
case 8:
|
||||
format = ZMBV_FORMAT_8BPP;
|
||||
pitch = lpbiIn->biWidth;
|
||||
break;
|
||||
case 15:
|
||||
format = ZMBV_FORMAT_15BPP;
|
||||
pitch = lpbiIn->biWidth * 2;
|
||||
break;
|
||||
case 16:
|
||||
format = ZMBV_FORMAT_16BPP;
|
||||
pitch = lpbiIn->biWidth * 2;
|
||||
break;
|
||||
case 32:
|
||||
format = ZMBV_FORMAT_32BPP;
|
||||
pitch = lpbiIn->biWidth * 4;
|
||||
break;
|
||||
}
|
||||
codec->PrepareCompressFrame( 0, format, 0, icinfo->lpOutput, 99999999);
|
||||
char *readPt = (char *)icinfo->lpbiInput;
|
||||
for(i = 0;i<lpbiIn->biHeight;i++) {
|
||||
codec->CompressLines(1, (void **)&readPt );
|
||||
readPt += pitch;
|
||||
}
|
||||
lpbiOut->biSizeImage = codec->FinishCompressFrame();
|
||||
return ICERR_OK;
|
||||
}
|
||||
|
||||
|
||||
DWORD CodecInst::CompressEnd() {
|
||||
if (codec)
|
||||
delete codec;
|
||||
codec = 0;
|
||||
return ICERR_OK;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
********************************************************************/
|
||||
|
||||
static bool CanDecompress(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut) {
|
||||
if (memcmp(&lpbiIn->biCompression,CODEC_4CC,4))
|
||||
return false;
|
||||
if (lpbiOut) {
|
||||
if (lpbiOut->biCompression!=0) return false;
|
||||
if (lpbiOut->biBitCount != 24) return false;
|
||||
if (lpbiIn->biWidth!=lpbiOut->biWidth || lpbiIn->biHeight!=lpbiOut->biHeight)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
********************************************************************/
|
||||
|
||||
|
||||
DWORD CodecInst::DecompressQuery(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut) {
|
||||
return CanDecompress(lpbiIn, lpbiOut) ? ICERR_OK : ICERR_BADFORMAT;
|
||||
}
|
||||
|
||||
DWORD CodecInst::DecompressGetFormat(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut) {
|
||||
if (memcmp(&lpbiIn->biCompression,CODEC_4CC,4))
|
||||
return ICERR_BADFORMAT;
|
||||
if (!lpbiOut) return sizeof(BITMAPINFOHEADER);
|
||||
*lpbiOut = *lpbiIn;
|
||||
lpbiOut->biPlanes = 1;
|
||||
lpbiOut->biSize=sizeof(BITMAPINFOHEADER);
|
||||
lpbiOut->biBitCount=24;
|
||||
lpbiOut->biCompression=0;
|
||||
return ICERR_OK;
|
||||
}
|
||||
|
||||
DWORD CodecInst::DecompressBegin(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut) {
|
||||
DecompressEnd(); // free resources if necessary
|
||||
if (!CanDecompress(lpbiIn, lpbiOut))
|
||||
return ICERR_BADFORMAT;
|
||||
codec=new VideoCodec();
|
||||
if (!codec)
|
||||
return ICERR_MEMORY;
|
||||
if (!codec->SetupDecompress( lpbiIn->biWidth, lpbiIn->biHeight))
|
||||
return ICERR_MEMORY;
|
||||
return ICERR_OK;
|
||||
}
|
||||
|
||||
DWORD CodecInst::Decompress(ICDECOMPRESS* icinfo, DWORD dwSize) {
|
||||
if (!codec || !icinfo)
|
||||
return ICERR_ABORT;
|
||||
if (codec->DecompressFrame( icinfo->lpInput, icinfo->lpbiInput->biSizeImage)) {
|
||||
codec->Output_UpsideDown_24(icinfo->lpOutput);
|
||||
icinfo->lpbiOutput->biSizeImage=icinfo->lpbiOutput->biWidth*icinfo->lpbiOutput->biHeight*icinfo->lpbiOutput->biBitCount/8;
|
||||
} else return ICERR_DONTDRAW;
|
||||
return ICERR_OK;
|
||||
}
|
||||
|
||||
|
||||
// palette-mapped output only
|
||||
DWORD CodecInst::DecompressGetPalette(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut) {
|
||||
return ICERR_BADFORMAT;
|
||||
}
|
||||
|
||||
DWORD CodecInst::DecompressEnd() {
|
||||
if (codec)
|
||||
delete codec;
|
||||
codec = 0;
|
||||
return ICERR_OK;
|
||||
}
|
Loading…
Add table
Reference in a new issue