Esempio n. 1
1
//-----------------------------------------------------------------------------
//	BugDlg_CompressScreenshot
//
//	Compress .BMP to .JPG, Delete .BMP
//-----------------------------------------------------------------------------
bool BugDlg_CompressScreenshot()
{
	if ( !g_bug_szScreenshot[0] )
	{
		return false;
	}

	bool bSuccess = false;
	HBITMAP hBitmap = NULL;
	HDC hDC = NULL;
	char *pBMPBits = NULL;

	CUtlBuffer buf( 0, 0 );

	hBitmap = (HBITMAP)LoadImage( NULL, g_bug_szScreenshot, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE );
	if ( !hBitmap )
		goto cleanUp;

	hDC = CreateCompatibleDC( NULL );
	if ( !hDC )
		goto cleanUp;

	BITMAPINFO bitmapInfo;
	ZeroMemory( &bitmapInfo, sizeof( BITMAPINFO ) );
	bitmapInfo.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );

	// populate the bmp info
	if ( !GetDIBits( hDC, hBitmap, 0, 0, NULL, &bitmapInfo, DIB_RGB_COLORS ) )
		goto cleanUp;

	pBMPBits = (char *)Sys_Alloc( bitmapInfo.bmiHeader.biSizeImage );
	if ( !pBMPBits )
		goto cleanUp;
	
	// could be bottom-up or top-down
	int nHeight = abs( bitmapInfo.bmiHeader.biHeight );

	if ( bitmapInfo.bmiHeader.biBitCount != 32 )
	{
		// unexpected format
		goto cleanUp;
	}

	if ( bitmapInfo.bmiHeader.biCompression != BI_RGB && bitmapInfo.bmiHeader.biCompression != BI_BITFIELDS )
	{
		// unexpected format
		goto cleanUp;
	}

	// don't want color masks
	bitmapInfo.bmiHeader.biCompression = BI_RGB;

	// get the raw bits
	if ( !GetDIBits( hDC, hBitmap, 0, nHeight, pBMPBits, &bitmapInfo, DIB_RGB_COLORS ) )
		goto cleanUp;

	JSAMPROW row_pointer[1]; 

	// compression data structure
	struct jpeg_compress_struct cinfo;
	ZeroMemory( &cinfo, sizeof( jpeg_compress_struct ) );

	// point at stderr
	struct jpeg_error_mgr jerr;
	cinfo.err = jpeg_std_error( &jerr );

	// create compressor
	jpeg_create_compress( &cinfo );

	// Hook CUtlBuffer to compression
	jpeg_UtlBuffer_dest( &cinfo, &buf );

	// image width and height, in pixels
	cinfo.image_width = bitmapInfo.bmiHeader.biWidth;
	cinfo.image_height = nHeight;
	cinfo.input_components = 3;
	cinfo.in_color_space = JCS_RGB;

	// Apply settings
	jpeg_set_defaults( &cinfo );
	jpeg_set_quality( &cinfo, 50, TRUE );

	// Start compressor
	jpeg_start_compress( &cinfo, TRUE);
	
	char *pRowBuffer = (char*)_alloca( bitmapInfo.bmiHeader.biWidth * 3 );
	row_pointer[0] = (JSAMPROW)pRowBuffer;

	// Write scanlines
	while ( cinfo.next_scanline < cinfo.image_height ) 
	{
		char *pSrc;
		if ( bitmapInfo.bmiHeader.biHeight < 0 )
		{
			// top down
			pSrc = &pBMPBits[cinfo.next_scanline * bitmapInfo.bmiHeader.biWidth * 4];
		}
		else
		{
			// bottom up
			pSrc = &pBMPBits[(nHeight-1 - cinfo.next_scanline) * bitmapInfo.bmiHeader.biWidth * 4];
		}
		
		// convert to BGR to RGB
		char *pDst = pRowBuffer;
		for ( int i=0; i<bitmapInfo.bmiHeader.biWidth; i++ )
		{
			pDst[0] = pSrc[2];
			pDst[1] = pSrc[1];
			pDst[2] = pSrc[0];
			pSrc += 4;
			pDst += 3;
		}		
		jpeg_write_scanlines( &cinfo, row_pointer, 1 );
	}

	// Finalize image
	jpeg_finish_compress( &cinfo );

	char jpgFilename[MAX_PATH];
	Sys_StripExtension( g_bug_szScreenshot, jpgFilename, sizeof( jpgFilename ) );
	Sys_AddExtension( ".jpg", jpgFilename, sizeof( jpgFilename ) );
	if ( !Sys_SaveFile( jpgFilename, buf.Base(), buf.TellMaxPut() ) )
		goto cleanUp;

	// remove the uncompressed version
	unlink( g_bug_szScreenshot );
	strcpy( g_bug_szScreenshot, jpgFilename );

	bSuccess = true;

cleanUp:
	if ( hBitmap )
		DeleteObject( hBitmap );
	if ( hDC )
		DeleteDC( hDC );
	if ( pBMPBits )
		Sys_Free( pBMPBits );

	return bSuccess;
}
Esempio n. 2
0
void VTFHandler_ConvertImageToJPG( CUtlBuffer &buf, unsigned char *imageData, uint32 width, uint32 height )
{
	int quality = 100;

	JSAMPROW row_pointer[1];     // pointer to JSAMPLE row[s]
	int row_stride;              // physical row width in image buffer

	// stderr handler
	struct jpeg_error_mgr jerr;

	// compression data structure
	struct jpeg_compress_struct cinfo;

	row_stride = width * 3; // JSAMPLEs per row in image_buffer

	// point at stderr
	cinfo.err = jpeg_std_error(&jerr);

	// create compressor
	jpeg_create_compress(&cinfo);

	// Hook CUtlBuffer to compression
	jpeg_UtlBuffer_dest(&cinfo, &buf);

	// image width and height, in pixels
	cinfo.image_width = width;
	cinfo.image_height = height;
	cinfo.input_components = 3;
	cinfo.in_color_space = JCS_RGB;

	// Apply settings
	jpeg_set_defaults(&cinfo);
	jpeg_set_quality(&cinfo, quality, TRUE);

	// Start compressor
	jpeg_start_compress(&cinfo, TRUE);

	// Write scanlines
	while (cinfo.next_scanline < cinfo.image_height)
	{
		row_pointer[0] = &imageData[cinfo.next_scanline * row_stride];
		jpeg_write_scanlines(&cinfo, row_pointer, 1);
	}

	// Finalize image
	jpeg_finish_compress(&cinfo);

	// Cleanup
	jpeg_destroy_compress(&cinfo);
}