⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dib.cpp

📁 About JPEG, executable on Visual C++
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	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 + -