📄 dib.cpp
字号:
unsigned char *pJpp;
pJpp = new unsigned char [dwSize];
cf.Read( pJpp, dwSize );
cf.Close();
int nWidth, nHeight, nHeadSize;
// DWORD dwTime0 = ::GetTickCount();
LARGE_INTEGER iLarge;
QueryPerformanceFrequency( &iLarge );
double dbFreq = (double) iLarge.QuadPart;
// Get starting time
QueryPerformanceCounter( &iLarge );
double dbBegin = (double) iLarge.QuadPart;
///////////////////////////////////////////////
CMiniJpegDecoder decoder;
decoder.GetImageInfo( pJpp, dwSize, nWidth, nHeight, nHeadSize );
m_width = nWidth;
m_height = nHeight;
///////////////////////////////////////////////
int nRowBytes = ( nWidth * 3 + 3 ) / 4 * 4; // BMP row bytes
int nDataBytes = nRowBytes * nHeight;
m_dwDibSize = nDataBytes + sizeof( BITMAPINFOHEADER );
m_nPaletteEntries = 0;
m_pPalette = NULL;
if( m_Palette.GetSafeHandle() != NULL )
m_Palette.DeleteObject();
m_pDib = new unsigned char [m_dwDibSize ];
m_pBIH = ( BITMAPINFOHEADER * ) m_pDib;
m_pDibBits = & m_pDib[ sizeof( BITMAPINFOHEADER ) ];
m_pBIH->biSize = sizeof(BITMAPINFOHEADER);
m_pBIH->biWidth = nWidth;
m_pBIH->biHeight = nHeight;
m_pBIH->biPlanes = 1;
m_pBIH->biBitCount = 24;
m_pBIH->biCompression = BI_RGB;
m_pBIH->biSizeImage = 0;
m_pBIH->biXPelsPerMeter = 0;
m_pBIH->biYPelsPerMeter = 0;
m_pBIH->biClrUsed = 0;
m_pBIH->biClrImportant = 0;
/////////////////////////////
decoder.DecompressImage( pJpp + nHeadSize, m_pDibBits );
/////////////////////////////
// Get ending time
QueryPerformanceCounter( &iLarge );
double dbEnd = (double) iLarge.QuadPart;
int ms = (int) (( dbEnd - dbBegin ) * 1000.0 / dbFreq );
CString str;
str.Format( "\nDecoding time = %d ", ms );
AfxMessageBox( str );
delete []pJpp;
return TRUE;
}
//////////////////////////////////////////////////////////////////////////////
// switch functions
void CDib::LoadJpg(CString fileName)
{
if( g_nJpegCodec == 0 )
LoadJpgWithIJGLib( fileName );
else
LoadJpgWithTonyLib( fileName );
}
void CDib::SaveJpg(CString filename, BOOL color, int quality)
{
if( g_nJpegCodec == 0 )
SaveJpgWithIJGLib( filename, color, quality );
else
SaveJpgWithTonyLib( filename, color, quality );
}
//////////////////////////////////////////////////////////////////////////////
// jpg load, using IJG code and JpegFile
void CDib::LoadJpgWithIJGLib(CString fileName)
{
unsigned char* buf;
// read to buffer tmp; buf is allocated here
// and read in width and height
buf = JpegFile::JpegFileToRGB(fileName, &m_width, &m_height);
//////////////////////
// set up for display
// do this before DWORD-alignment!!!
// this works on packed (not DWORD-aligned) buffers
// swap red and blue for display
JpegFile::BGRFromRGB(buf, m_width, m_height);
// vertical flip for display
JpegFile::VertFlipBuf(buf, m_width * 3, m_height);
////////////////////////
// making bmp here
//row bytes must be divided by 4; if not, patch zero bytes
m_rowbytes = ( m_width * 3 + 3 ) / 4 * 4;
// only the size of memory dib; not include fileheader
m_dwDibSize = m_rowbytes * m_height + sizeof(BITMAPINFOHEADER);
// allocate memory
m_pDib = new unsigned char [m_dwDibSize];
// make infoheader
BITMAPINFOHEADER bmiHeader;
bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmiHeader.biWidth = m_width;
bmiHeader.biHeight = m_height;
bmiHeader.biPlanes = 1;
bmiHeader.biBitCount = 24;
bmiHeader.biCompression = BI_RGB;
bmiHeader.biSizeImage = 0;
bmiHeader.biXPelsPerMeter = 0;
bmiHeader.biYPelsPerMeter = 0;
bmiHeader.biClrUsed = 0;
bmiHeader.biClrImportant = 0;
m_pBIH = (BITMAPINFOHEADER *) m_pDib;
memcpy( m_pBIH, &bmiHeader, sizeof(BITMAPINFOHEADER) );
// no palette
m_pPalette = (RGBQUAD *) &m_pDib[sizeof(BITMAPINFOHEADER)];
m_nPaletteEntries = 0;
// Point m_pDibBits to the actual Dib bits data.
m_pDibBits = &m_pDib[ sizeof(BITMAPINFOHEADER) +
m_nPaletteEntries * sizeof(RGBQUAD)];
// get data
BYTE *pSource, *pTarget;
pSource = buf;
pTarget = m_pDibBits;
for( UINT i=0; i<m_height; i++ )
{
memcpy( pTarget, pSource, m_width * 3 );
pSource += m_width * 3;
pTarget += m_rowbytes;// here patch zero data
}
// end making bmp
////////////////////////
// free buf
if (buf!=NULL) {
delete [] buf;
buf=NULL;
}
}
///////////////////////////////////////////////////////////////////////////////
// jpg save, using IJG code and JpegFile
void CDib::SaveJpgWithIJGLib(CString filename, BOOL color, int quality)
{
// note, because i'm lazy, most image data in this app
// is handled as 24-bit images. this makes the DIB
// conversion easier. 1,4,8, 15/16 and 32 bit DIBs are
// significantly more difficult to handle.
m_width = m_pBIH->biWidth;
m_height = m_pBIH->biHeight;
m_rowbytes = ( m_width * 3 + 3 ) / 4 * 4;
unsigned char* buf = new unsigned char[m_width * 3 * m_height];
// making compact data
BYTE *pSource, *pTarget;
pSource = m_pDibBits;
pTarget = buf;
for( UINT i=0; i<m_height; i++ )
{
memcpy( pTarget, pSource, m_width * 3 );
pSource += m_rowbytes;
pTarget += m_width * 3;
}
// we vertical flip for display. undo that.
JpegFile::VertFlipBuf(buf, m_width * 3, m_height);
// we swap red and blue for display, undo that.
JpegFile::BGRFromRGB(buf, m_width, m_height);
// save RGB packed buffer to JPG
BOOL ok=JpegFile::RGBToJpegFile(filename,
buf,
m_width,
m_height,
color,
quality);// 75);// quality value 1-100.
// free buf
if (buf!=NULL) {
delete [] buf;
buf=NULL;
}
if (!ok) {
AfxMessageBox("Write Error");
}
}
///////////////////////////////////////////////////////////////////////////////
void CDib::LoadJpgWithTonyLib(CString fileName)
{
// AfxMessageBox("LoadJpgWithTonyLib()");
///////////////////////////////////////////////
// Step 1: Attempt to open the file
CFile cf;
if( !cf.Open( fileName, CFile::modeRead ) )
{
AfxMessageBox("Can not read this jpg file!");
return;
}
DWORD dwSize;
dwSize = cf.GetLength();
unsigned char *pJpg;
pJpg = new unsigned char [dwSize];
cf.Read( pJpg, dwSize );
cf.Close();
int nWidth, nHeight, nHeadSize;
LARGE_INTEGER iLarge;
QueryPerformanceFrequency( &iLarge );
double dbFreq = (double) iLarge.QuadPart;
// Get starting time
QueryPerformanceCounter( &iLarge );
double dbBegin = (double) iLarge.QuadPart;
///////////////////////////////////////////////
// step 2: Read jpg header
CTonyJpegDecoder decoder;
if( decoder.ReadJpgHeader( pJpg, dwSize, nWidth, nHeight, nHeadSize ) == false )
{
AfxMessageBox("Format not supported, sorry!");
return;
}
m_width = nWidth;
m_height = nHeight;
///////////////////////////////////////////////
// step 3: prepare bmp to receive data
int nRowBytes = ( nWidth * 3 + 3 ) / 4 * 4; // BMP row bytes
int nDataBytes = nRowBytes * nHeight;
m_dwDibSize = nDataBytes + sizeof( BITMAPINFOHEADER );
m_nPaletteEntries = 0;
m_pPalette = NULL;
if( m_Palette.GetSafeHandle() != NULL )
m_Palette.DeleteObject();
m_pDib = new unsigned char [m_dwDibSize ];
m_pBIH = ( BITMAPINFOHEADER * ) m_pDib;
m_pDibBits = & m_pDib[ sizeof( BITMAPINFOHEADER ) ];
m_pBIH->biSize = sizeof(BITMAPINFOHEADER);
m_pBIH->biWidth = nWidth;
m_pBIH->biHeight = nHeight;
m_pBIH->biPlanes = 1;
m_pBIH->biBitCount = 24;
m_pBIH->biCompression = BI_RGB;
m_pBIH->biSizeImage = 0;
m_pBIH->biXPelsPerMeter = 0;
m_pBIH->biYPelsPerMeter = 0;
m_pBIH->biClrUsed = 0;
m_pBIH->biClrImportant = 0;
/////////////////////////////
// step 4: decompress to bmp buffer
decoder.DecompressImage( pJpg + nHeadSize, m_pDibBits );
/////////////////////////////
// Get ending time
QueryPerformanceCounter( &iLarge );
double dbEnd = (double) iLarge.QuadPart;
int ms = (int) (( dbEnd - dbBegin ) * 1000.0 / dbFreq );
CString str;
str.Format( "\nDecoding time = %d ", ms );
AfxMessageBox( str );
delete []pJpg;
}
///////////////////////////////////////////////////////////////////////////////
void CDib::SaveJpgWithTonyLib(CString filename, BOOL color, int quality)
{
// AfxMessageBox("SaveJpgWithTonyLib()");
int nOutputBytes = 0;
unsigned char *pJpg;
pJpg = new unsigned char [m_dwDibSize];//cannot bigger than bmp
LARGE_INTEGER iLarge;
QueryPerformanceFrequency( &iLarge );
double dbFreq = (double) iLarge.QuadPart;
// Get starting time
QueryPerformanceCounter( &iLarge );
double dbBegin = (double) iLarge.QuadPart;
/////////////////////////////////////////////////////
/*
* influence quant table:
* 25: 16->32; much quantization.
* 50: 16->16; moderate quantization.
* 75: 16->8; less quantization.
*/
CTonyJpegEncoder encoder( quality );
encoder.CompressImage( m_pDibBits, pJpg,
m_pBIH->biWidth, m_pBIH->biHeight, nOutputBytes );
//////////////////////////////////////////////////////
// DWORD dwTime1 = ::GetTickCount();
// nms = dwTime1 - dwTime0;
// Get ending time
QueryPerformanceCounter( &iLarge );
double dbEnd = (double) iLarge.QuadPart;
int nms = (int) (( dbEnd - dbBegin ) * 1000.0 / dbFreq );
float ratio = (float) m_dwDibSize / nOutputBytes;
CString str;
str.Format( "nBytes = %d, Compression Ratio = %f, time = %d ",
nOutputBytes, ratio, nms );
AfxMessageBox( str );
// Attempt to create the file
CFile cf;
if( !cf.Open( filename, CFile::modeCreate | CFile::modeWrite ) )
{
AfxMessageBox("Can not create jpg file!");
return;
}
cf.Write( pJpg, nOutputBytes );
delete []pJpg;
}
///////////////////////////////////////////////////////////////////////////////
// file end //
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -