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

📄 jpeg.cpp

📁 一个国人自己实现图像库的程序(有参考价值)
💻 CPP
字号:
#include "stdafx.h"
#include "..\..\Include\Pic\Image.h"
#include <setjmp.h>

struct ima_error_mgr
{
	struct jpeg_error_mgr pub ; // "public" field
	jmp_buf		setjmp_buffer ;
	CHAR		buffer[255] ; // error message
} ;
typedef ima_error_mgr *ima_error_ptr;

static void ima_jpeg_error_exit (j_common_ptr cinfo)
{
	ima_error_ptr myerr = (ima_error_ptr) cinfo->err ;
	myerr->pub.format_message (cinfo, myerr->buffer) ; // Create the message
	longjmp (myerr->setjmp_buffer, TRUE) ; // return TRUE to setjmp call
}
//===================================================================
BOOL  FCImage::LoadJpeg (BYTE * pStart, int iFileSize)
{
	struct jpeg_decompress_struct	cinfo ;

	// Set up the normal JPEG error routines, then override error_exit.
	struct ima_error_mgr jerr ;
	cinfo.err = jpeg_std_error (&jerr.pub) ;
	jerr.pub.error_exit = ima_jpeg_error_exit ;
	if (setjmp (jerr.setjmp_buffer))
	{
		//::MessageBox (NULL, jerr.buffer, TEXT("error!"), MB_OK) ;
		jpeg_destroy_decompress (&cinfo) ;
		return FALSE ;
	}

	// create JPEG decompression object.
	jpeg_create_decompress (&cinfo) ;

	// Specify data source
	FCJpegStream	src (pStart, iFileSize) ;
	cinfo.src = &src ;
	
	// Read file parameters
	jpeg_read_header (&cinfo, TRUE) ;

	// validate the parameter
	if ((cinfo.image_width == 0) || (cinfo.image_height == 0) || (cinfo.jpeg_color_space == JCS_UNKNOWN))
	{
		jpeg_destroy_decompress (&cinfo) ;
		return FALSE ;
	}

	// create DIB
	if (!this->Create (cinfo.image_width, cinfo.image_height, 8 * cinfo.num_components))
	{
		jpeg_destroy_decompress (&cinfo) ;
		return FALSE ;
	}

	if (cinfo.jpeg_color_space == JCS_GRAYSCALE)
		this->SetGrayPalette () ;

	// decompression data
	jpeg_start_decompress (&cinfo) ;
	while (cinfo.output_scanline < cinfo.output_height)
	{
		BYTE	* pLine = this->GetBits (cinfo.output_scanline) ;
		jpeg_read_scanlines (&cinfo, &pLine, 1) ;
		// Swap red and blue components
		if (cinfo.num_components >= 3)
			for (int x=0 ; x < this->Width() ; x++, pLine += cinfo.num_components)
			{
				BYTE	temp = pLine[0] ;
				pLine[0] = pLine[2] ;
				pLine[2] = temp ;
			}
	}
	jpeg_finish_decompress (&cinfo) ;

	// end of load
	jpeg_destroy_decompress (&cinfo) ;
	return TRUE ;
}
//===================================================================
BOOL  FCImage::LoadJpeg (PCTSTR resName, PCTSTR resType)
{
	HRSRC	res = ::FindResource (NULL, resName, resType) ;
	HGLOBAL	gol = ::LoadResource (NULL, res) ;
	BYTE	* pJpegData = (BYTE *) ::LockResource (gol) ;
	return (pJpegData == NULL) ? FALSE : this->LoadJpeg (pJpegData, ::SizeofResource (NULL, res)) ;
}
//===================================================================
BOOL  FCImage::LoadJpeg (PCTSTR szFileName)
{
	BOOL			bRet = FALSE ;
	BYTE			* pStart = NULL ;
	HANDLE			hMap = NULL ;
	HANDLE			hFile = INVALID_HANDLE_VALUE ;

	if (pFooDib->hBitmap != NULL)
		this->Unload () ;

	// mapping the image file
	pStart = this->__fooImageReadFile (szFileName, &hFile, &hMap) ;
	if (pStart != NULL)
		bRet = this->LoadJpeg (pStart, ::GetFileSize(hFile, NULL)) ; // 读文件
	this->__fooImageUnmapFile ((BYTE *)pStart, hMap, hFile) ;
	return bRet ;
}
//===================================================================
BOOL  FCImage::SaveJpeg (PCTSTR szFile_Name, DWORD dwQuality)
{
	switch (this->ColorBits ())
	{
		case 24 : break ; // RGB		
		case 8 :
			if (this->IsGrayPalette ()) // GreyScale
				break ;
		default :
			//::MessageBox (NULL, TEXT("Only RGB or GreyScale images can be saved as JPEG"), TEXT("error!"), MB_OK) ;
			return FALSE ;
	}
	
	struct jpeg_compress_struct cinfo ;
	FILE   * pfile = NULL ;

	// Set up the normal JPEG error routines, then override error_exit.
	// If error occur, file can be close but still exist.
	struct ima_error_mgr jerr ;
	cinfo.err = jpeg_std_error (&jerr.pub) ;
	jerr.pub.error_exit = ima_jpeg_error_exit ;
	if (setjmp (jerr.setjmp_buffer))
	{
		//::MessageBox (NULL, jerr.buffer, TEXT("error!"), MB_OK) ;
		if (pfile != NULL)	fclose (pfile) ;
		jpeg_destroy_compress (&cinfo) ;
		return FALSE ;
	}

	// create JPEG compression object.
	jpeg_create_compress (&cinfo) ;
	pfile = ::fopen (szFile_Name, "wb") ;
	jpeg_stdio_dest (&cinfo, (FILE *)pfile) ;

	// set image pixel format
	cinfo.image_width  = this->Width() ;
	cinfo.image_height = this->Height() ;
	cinfo.input_components = this->ColorBits() / 8 ; // 1 or 3
	cinfo.in_color_space = (ColorBits() == 24) ? JCS_RGB : JCS_GRAYSCALE ;
	jpeg_set_defaults (&cinfo) ; // Use the library's default routine
	jpeg_set_quality (&cinfo, dwQuality, TRUE) ; // set quality

	// write file
	jpeg_start_compress (&cinfo, TRUE) ;
	DWORD		dwPitch = this->GetPitch() ;
	BYTE		* pLineBuf = new BYTE[dwPitch] ;
	int			iWidth = 3 * Width() ;
	while (cinfo.next_scanline < cinfo.image_height)
	{
		BYTE	* pLine = this->GetBits (cinfo.next_scanline) ;
		if (this->ColorBits() == 24)
		{
			for (int x=0 ; x < iWidth ; x += 3, pLine += 3)
			{
				pLineBuf[x] = pLine[2] ;
				pLineBuf[x+1] = pLine[1] ;
				pLineBuf[x+2] = pLine[0] ;
			}
			pLine = pLineBuf ;
		}
		jpeg_write_scanlines (&cinfo, &pLine, TRUE) ;
	}
	delete[] pLineBuf ;
	jpeg_finish_compress (&cinfo) ;

	// end of save
	if (pfile != NULL)	fclose (pfile) ;
	jpeg_destroy_compress (&cinfo) ;
	return TRUE ;
}
//===================================================================

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -