📄 jpeg.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 + -