📄 mjpgtojpgdlg.cpp
字号:
// MJPGtoJPGDlg.cpp : implementation file
//
#include "stdafx.h"
#include "MJPGtoJPG.h"
#include "MJPGtoJPGDlg.h"
#include "dib.h"
#include "vfw.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMJPGtoJPGDlg dialog
CMJPGtoJPGDlg::CMJPGtoJPGDlg(CWnd* pParent /*=NULL*/)
: CDialog(CMJPGtoJPGDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CMJPGtoJPGDlg)
m_From = _T("");
m_To = _T("");
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CMJPGtoJPGDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMJPGtoJPGDlg)
DDX_Control(pDX, IDC_TO, m_CTo);
DDX_Control(pDX, IDC_FROM, m_CFrom);
DDX_Text(pDX, IDC_FROM, m_From);
DDX_Text(pDX, IDC_TO, m_To);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CMJPGtoJPGDlg, CDialog)
//{{AFX_MSG_MAP(CMJPGtoJPGDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BROWSEFROM, OnBrowsefrom)
ON_BN_CLICKED(IDC_BROWSETO, OnBrowseto)
ON_BN_CLICKED(IDC_COMPRESS, OnCompress)
ON_BN_CLICKED(IDC_SAVE, OnSave)
ON_BN_CLICKED(IDC_EXTRACT, OnSaveSeq)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMJPGtoJPGDlg message handlers
BOOL CMJPGtoJPGDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
m_hcompdib = 0;
return TRUE; // return TRUE unless you set the focus to a control
}
void CMJPGtoJPGDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CMJPGtoJPGDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CMJPGtoJPGDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CMJPGtoJPGDlg::OnBrowsefrom()
{
OPENFILENAME ofn;
char szBuffer[255] = "AVI\0*.avi\0Bitmaps\0*.dib;*.bmp;*.rle\0All\0*.*\0\0";
char szFileName[255];
strcpy(szFileName, "");
/* prompt user for file to open */
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = m_hWnd;
ofn.hInstance = NULL;
ofn.lpstrFilter = szBuffer;
ofn.lpstrCustomFilter = NULL;
ofn.nMaxCustFilter = 0;
ofn.nFilterIndex = 0;
ofn.lpstrFile = szFileName;
ofn.nMaxFile = sizeof(szFileName);
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.lpstrTitle = NULL;
ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
ofn.nFileOffset = 0;
ofn.nFileExtension = 0;
ofn.lpstrDefExt = NULL;
ofn.lCustData = 0;
ofn.lpfnHook = NULL;
ofn.lpTemplateName = NULL;
if (GetOpenFileName(&ofn)) {
m_From = szFileName;
m_CFrom.SetWindowText(m_From);
strcat(szFileName, ".jpg");
m_To = szFileName;
m_CTo.SetWindowText(m_To);
}
}
void CMJPGtoJPGDlg::OnBrowseto()
{
OPENFILENAME ofn;
char szBuffer[255] = "JPEG\0*.jpg\0";
char szFileName[255];
m_CTo.GetWindowText(m_To);
strcpy(szFileName, m_To);
/* prompt user for file to save */
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = m_hWnd;
ofn.hInstance = NULL;
ofn.lpstrFilter = szBuffer;
ofn.lpstrCustomFilter = NULL;
ofn.nMaxCustFilter = 0;
ofn.nFilterIndex = 0;
ofn.lpstrFile = szFileName;
ofn.nMaxFile = sizeof(szFileName);
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.lpstrTitle = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
ofn.nFileOffset = 0;
ofn.nFileExtension = 0;
ofn.lpstrDefExt = NULL;
ofn.lCustData = 0;
ofn.lpfnHook = NULL;
ofn.lpTemplateName = NULL;
if (GetSaveFileName(&ofn))
{
m_To = szFileName;
m_CTo.SetWindowText(m_To);
}
}
/* Default SOI + APP0 'JFIF' + DHT Segments */
BYTE MJPGDefSOI_APP0_DHTSeg[] = {
/* JPEG SOI Segment */
0xFF,0xD8,
/* JPEG APP0 Segment, 'JFIF' in JPEG data, 'AVI1' in MJPG data*/
0xFF,0xE0,0x00,0x10,0x4A,0x46,0x49,0x46,0x00,0x01,0x01,0x00,0x00,0x01,0x00,0x01,0x00,0x00,
/* JPEG DHT Segment for YCrCb omitted from MJPG data */
0xFF,0xC4,0x01,0xA2,
0x00,0x00,0x01,0x05,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x01,0x00,0x03,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
0x08,0x09,0x0A,0x0B,0x10,0x00,0x02,0x01,0x03,0x03,0x02,0x04,0x03,0x05,0x05,0x04,0x04,0x00,
0x00,0x01,0x7D,0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,
0x07,0x22,0x71,0x14,0x32,0x81,0x91,0xA1,0x08,0x23,0x42,0xB1,0xC1,0x15,0x52,0xD1,0xF0,0x24,
0x33,0x62,0x72,0x82,0x09,0x0A,0x16,0x17,0x18,0x19,0x1A,0x25,0x26,0x27,0x28,0x29,0x2A,0x34,
0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x53,0x54,0x55,0x56,
0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x73,0x74,0x75,0x76,0x77,0x78,
0x79,0x7A,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,
0x9A,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,
0xBA,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,
0xDA,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,
0xF8,0xF9,0xFA,0x11,0x00,0x02,0x01,0x02,0x04,0x04,0x03,0x04,0x07,0x05,0x04,0x04,0x00,0x01,
0x02,0x77,0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,
0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,0xA1,0xB1,0xC1,0x09,0x23,0x33,0x52,0xF0,0x15,0x62,
0x72,0xD1,0x0A,0x16,0x24,0x34,0xE1,0x25,0xF1,0x17,0x18,0x19,0x1A,0x26,0x27,0x28,0x29,0x2A,
0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x53,0x54,0x55,0x56,
0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x73,0x74,0x75,0x76,0x77,0x78,
0x79,0x7A,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,
0x99,0x9A,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,
0xB9,0xBA,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,
0xD9,0xDA,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,
0xF9,0xFA
};
/* End SOI + APP0 'JFIF' + DHT default */
#define SOIAPP0LEN 20
void CMJPGtoJPGDlg::OnSave()
{
LPBITMAPINFOHEADER lpbi;
LPBYTE lpbits;
int fh;
OFSTRUCT of;
if (!m_hcompdib)
return;
m_CTo.GetWindowText(m_To);
// Create JPEG file
fh = OpenFile(m_To,&of,OF_CREATE|OF_READWRITE);
if (fh == -1)
return;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(m_hcompdib);
if (lpbi == NULL)
return;
if (lpbi->biCompression != mmioFOURCC('M', 'J', 'P', 'G'))
{
GlobalUnlock(m_hcompdib);
return;
}
// Point to start of JPEG image in compressed DIB, skip SOI and APP0 segments.
lpbits = (LPBYTE)lpbi + lpbi->biSize + SOIAPP0LEN;
// Write default SOI, APP0 and DHT segments
_lwrite(fh, (LPSTR)MJPGDefSOI_APP0_DHTSeg, sizeof(MJPGDefSOI_APP0_DHTSeg));
// Write rest of JPEG image
_lwrite(fh, (LPSTR)lpbits, lpbi->biSizeImage - SOIAPP0LEN);
GlobalUnlock(m_hcompdib);
GlobalFree(m_hcompdib);
m_hcompdib = 0;
_lclose(fh);
}
void CMJPGtoJPGDlg::OnCompress()
{
// Load uncompressed DIB
HANDLE hdib = OpenDIB((LPSTR)(LPCTSTR)m_From);
if (hdib == 0)
{
AfxMessageBox("Source file is not a BITMAP file !");
return;
}
LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)GlobalLock(hdib);
// If not a 8 bits DIB (not supported by MJPEG codec) ...
if (lpbi->biBitCount > 8)
{
// ... Compress it
HIC hicc = ICOpen(ICTYPE_VIDEO, mmioFOURCC('M', 'J', 'P', 'G'), ICMODE_COMPRESS);
m_hcompdib = ICImageCompress(
hicc, // compressor to use
0, // flags
(LPBITMAPINFO)lpbi,// format to compress from
DibPtr(lpbi), // bits to compress
NULL, // output format (default)
7500, // quality to use.
NULL); // size of output (whatever)
ICClose(hicc);
}
GlobalUnlock(hdib);
GlobalFree(hdib);
OnSave();
}
void SaveJPEG(LPBYTE lpSOI, int len, LPSTR lpszFile)
{
int fh;
OFSTRUCT of;
// Create JPEG file
fh = OpenFile(lpszFile,&of,OF_CREATE|OF_READWRITE);
if (fh == -1)
return;
// Point to start of JPEG image in compressed DIB, skip SOI and APP0 segments.
lpSOI = lpSOI + SOIAPP0LEN;
// Write default SOI, APP0 and DHT segments
_lwrite(fh, (LPSTR)MJPGDefSOI_APP0_DHTSeg, sizeof(MJPGDefSOI_APP0_DHTSeg));
// Write rest of JPEG image
_lwrite(fh, (LPSTR)lpSOI, len);
_lclose(fh);
}
void CMJPGtoJPGDlg::OnSaveSeq()
{
PAVISTREAM pas;
LONG lFmtLength;
LPBITMAPINFOHEADER lpSrcFmt=NULL;
LONG lLength;
AVISTREAMINFO si;
LPBYTE lpSrc=NULL;
LONG lIndex;
LONG lFrames;
LPBYTE lpSOI=NULL;
LPBYTE lpSOI_2=NULL;
LPBYTE lpLimit=NULL;
CString sIndex;
CString sFileName;
int len;
AVIFileInit();
AVIStreamOpenFromFile(&pas,
(LPSTR)(LPCTSTR)m_From,
streamtypeVIDEO,
0,
OF_READ | OF_SHARE_DENY_NONE, //OF_SHARE_EXCLUSIVE,
NULL);
AVIStreamFormatSize(pas, 0, &lFmtLength);
lpSrcFmt = (LPBITMAPINFOHEADER)malloc(lFmtLength);
AVIStreamReadFormat(pas, 0, lpSrcFmt, &lFmtLength);
if ((lpSrcFmt->biCompression != mmioFOURCC('M', 'J', 'P', 'G')) &&
(lpSrcFmt->biCompression != mmioFOURCC('m', 'j', 'p', 'g')) &&
(lpSrcFmt->biCompression != mmioFOURCC('d', 'm', 'b', '1')) &&
(lpSrcFmt->biCompression != mmioFOURCC('j', 'p', 'e', 'g')))
{
if (lpSrcFmt)
free(lpSrcFmt);
if (pas)
AVIStreamRelease(pas);
AVIFileExit();
AfxMessageBox("Source file is not an AVI MJPEG file !");
return;
}
lLength = (ULONG)lpSrcFmt->biSizeImage;
AVIStreamInfo(pas, &si, AVIStreamInfo(pas, NULL, 0));
if (si.dwSuggestedBufferSize)
if ((LONG)si.dwSuggestedBufferSize > lLength)
lLength = (LONG)si.dwSuggestedBufferSize;
if (!lLength)
lLength = (ULONG)(lpSrcFmt->biHeight * lpSrcFmt->biWidth * ((lpSrcFmt->biBitCount / 8) + (lpSrcFmt->biBitCount % 8)));
lpSrc = (LPBYTE)malloc((lLength / 16) * 16 + 16);
m_CTo.GetWindowText(m_To);
lIndex = 0;
lFrames = AVIStreamLength(pas);
while (lFrames--)
{
if (AVIStreamRead(pas, lIndex++, 1, lpSrc, lLength, (long *)&lpSrcFmt->biSizeImage, NULL) == 0)
{
lpLimit = lpSrc + lpSrcFmt->biSizeImage;
lpSOI = lpSrc;
// sure to start with SOI, skip padding ...
while (*(WORD *)lpSOI != 0xD8FF && ++lpSOI < lpLimit);
if (lpSOI >= lpLimit)
lpSOI = NULL;
lpSOI_2 = lpSOI + 2;
// look for a second field (second SOI) ...
while (*(WORD *)lpSOI_2 != 0xD8FF && ++lpSOI_2 < lpLimit);
if (lpSOI_2 >= lpLimit)
lpSOI_2 = NULL;
if (lpSOI)
{
if (lpSOI_2)
len = lpSOI_2 - lpSOI;
else
len = lpLimit - lpSOI;
sIndex.Format("%.04d", lIndex);
sFileName = m_To + "." + sIndex + ".jpg";
SetWindowText(sFileName);
UpdateWindow();
SaveJPEG(lpSOI, len, (LPSTR)(LPCTSTR)sFileName);
}
if (lpSOI_2)
{
len = lpLimit - lpSOI_2;
sIndex.Format("%.04d_2", lIndex);
sFileName = m_To + "." + sIndex + ".jpg";
SetWindowText(sFileName);
UpdateWindow();
SaveJPEG(lpSOI_2, len, (LPSTR)(LPCTSTR)sFileName);
}
}
}
if (lpSrcFmt)
free(lpSrcFmt);
if (lpSrc)
free(lpSrc);
if (pas)
AVIStreamRelease(pas);
AVIFileExit();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -