📄 jpeg.cpp
字号:
}
//////////////////////////////////////////////////////////////
//
// BYTE* CJpeg::ClearDwordAlign
//
//////////////////////////////////////////////////////////////
BYTE* CJpeg::ClearDwordAlign(BYTE *inBuf,
UINT widthPix,
UINT widthBytes,
UINT height,int n)
{
if (inBuf==NULL)
return FALSE;
BYTE *tmp;
tmp=(BYTE *)new BYTE[height * widthPix * n];
if (tmp==NULL)
return NULL;
UINT row;
for (row=0;row<height;row++)
{
memcpy((tmp+row * widthPix * n),
(inBuf + row * widthBytes),
widthPix * n);
}
return tmp;
}
/////////////////////////////////////////////////////////////////////////////
//
//读取JPEG文件
//参数:
//fileName——包含JPEG文件的全路径名
//uWidth——图像的宽度
//uHeight——图像的高度
//返回值为解压后的数据缓冲区指针
//
//////////////////////////////////////////////////////////////////////////////
BYTE* CJpeg::ReadJPEGFile(LPCSTR fileName, UINT *uWidth, UINT *uHeight, int *n)
{
*uWidth=0;
*uHeight=0;
//定义JPEG文件的解压信息
struct jpeg_decompress_struct cinfo;
//定义JPEG文件的错误信息
struct my_error_mgr jerr;
//定义缓冲区
FILE * infile;
JSAMPARRAY buffer;
int row_stride;
char buf[250];
//打开JPEG文件
if ((infile = fopen(fileName, "rb")) == NULL)
{
sprintf(buf, "JPEG :\nCan't open %s\n", fileName);
m_strJPEGError = buf;
return NULL;
}
//为JPEG文件解压对象分配内存并对其初始化
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = my_error_exit;
if (setjmp(jerr.setjmp_buffer))
{
jpeg_destroy_decompress(&cinfo);
fclose(infile);
return NULL;
}
jpeg_create_decompress(&cinfo);
//设定数据源
jpeg_stdio_src(&cinfo, infile);
//读取JPEG文件参数
(void) jpeg_read_header(&cinfo, TRUE);
//开始解压
(void) jpeg_start_decompress(&cinfo);
BYTE *dataBuf;
dataBuf=(BYTE *)new BYTE[cinfo.output_width * cinfo.output_components * cinfo.output_height];
if (dataBuf==NULL)
{
m_strJPEGError = "JpegFile :\nOut of memory";
jpeg_destroy_decompress(&cinfo);
fclose(infile);
return NULL;
}
*uWidth = cinfo.output_width;
*uHeight = cinfo.output_height;
*n = cinfo.out_color_components;
row_stride = cinfo.output_width * cinfo.output_components;
buffer = (*cinfo.mem->alloc_sarray)
((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
//读取扫描线
while (cinfo.output_scanline < cinfo.output_height)
{
(void) jpeg_read_scanlines(&cinfo, buffer, 1);
if (cinfo.out_color_components==3)
{
j_putRGBScanline(buffer[0],
*uWidth,
dataBuf,
cinfo.output_scanline-1);
}
else if (cinfo.out_color_components==1)
{
//j_putGrayScanlineToRGB(buffer[0], *uWidth, dataBuf, cinfo.output_scanline-1);
j_putGrayScanline(buffer[0], *uWidth, dataBuf, cinfo.output_scanline-1);
}
}
//完成解压
(void) jpeg_finish_decompress(&cinfo);
//释放JPEG解压对象
jpeg_destroy_decompress(&cinfo);
fclose(infile);
return dataBuf;
}
///////////////////////////////////////////////////////////////////
//
// BOOL CJpeg::WriteJPEGFile
//
////////////////////////////////////////////////////////////////////
BOOL CJpeg::WriteJPEGFile(LPCSTR fileName,
BYTE *dataBuf,
UINT widthPix,
UINT height,
BOOL color,
int quality)
{
if (dataBuf==NULL)
return FALSE;
if (widthPix==0)
return FALSE;
if (height==0)
return FALSE;
LPBYTE tmp;
if (!color)
{
tmp = (BYTE*)new BYTE[widthPix*height];
if (tmp==NULL)
{
m_strJPEGError = "Memory error";
return FALSE;
}
UINT row,col;
for (row=0;row<height;row++)
{
for (col=0;col<widthPix;col++)
{
//LPBYTE pRed, pGrn, pBlu;
//pRed = dataBuf + row * widthPix * 3 + col * 3;
//pGrn = dataBuf + row * widthPix * 3 + col * 3 + 1;
//pBlu = dataBuf + row * widthPix * 3 + col * 3 + 2;
LPBYTE pG;
pG = dataBuf + row * widthPix + col;
// 计算图像亮度值
//int lum = (int)(((double)(*pRed) + (double)(*pGrn) + (double)(*pBlu))/3.0);
//int lum = (int)(.299 * (double)(*pRed) + .587 * (double)(*pGrn) + .114 * (double)(*pBlu));
int lum = *pG;
LPBYTE pGray;
pGray = tmp + row * widthPix + col;
*pGray = (BYTE)lum;
}
}
}
//定义压缩信息
struct jpeg_compress_struct cinfo;
//定义缓冲区
FILE * outfile;
int row_stride;
//定义错误信息
struct my_error_mgr jerr;
//为JPEG文件压缩对象分配内存并对其初始化
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = my_error_exit;
if (setjmp(jerr.setjmp_buffer))
{
jpeg_destroy_compress(&cinfo);
fclose(outfile);
if (!color)
{
delete [] tmp;
}
return FALSE;
}
jpeg_create_compress(&cinfo);
//打开文件并设定数据目标
if ((outfile = fopen(fileName, "wb")) == NULL)
{
char buf[250];
sprintf(buf, "JpegFile :\nCan't open %s\n", fileName);
m_strJPEGError = buf;
return FALSE;
}
jpeg_stdio_dest(&cinfo, outfile);
//设置压缩参数
cinfo.image_width = widthPix;
cinfo.image_height = height;
if (color)
{
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
row_stride = widthPix * 3;
}
else
{
cinfo.input_components = 1;
cinfo.in_color_space = JCS_GRAYSCALE;
row_stride = widthPix;
}
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, quality, TRUE );
//开始压缩
jpeg_start_compress(&cinfo, TRUE);
//写入扫描线
//row_stride = widthPix * 3;
while (cinfo.next_scanline < cinfo.image_height)
{
LPBYTE outRow;
if (color)
{
outRow = dataBuf + (cinfo.next_scanline * widthPix * 3);
}
else
{
outRow = tmp + (cinfo.next_scanline * widthPix);
}
(void) jpeg_write_scanlines(&cinfo, &outRow, 1);
}
//完成压缩
jpeg_finish_compress(&cinfo);
fclose(outfile);
//释放压缩对象
jpeg_destroy_compress(&cinfo);
if (!color)
delete [] tmp;
return TRUE;
}
//
// stash a scanline
//
void j_putRGBScanline(BYTE *jpegline,
int widthPix,
BYTE *outBuf,
int row)
{
int offset = row * widthPix * 3;
int count;
for (count=0;count<widthPix;count++) {
BYTE iRed, iBlu, iGrn;
LPBYTE oRed, oBlu, oGrn;
iRed = *(jpegline + count * 3 + 0);
iGrn = *(jpegline + count * 3 + 1);
iBlu = *(jpegline + count * 3 + 2);
oRed = outBuf + offset + count * 3 + 0;
oGrn = outBuf + offset + count * 3 + 1;
oBlu = outBuf + offset + count * 3 + 2;
*oRed = iRed;
*oGrn = iGrn;
*oBlu = iBlu;
}
}
//
// stash a gray scanline
//
void j_putGrayScanlineToRGB(BYTE *jpegline,
int widthPix,
BYTE *outBuf,
int row)
{
int offset = row * widthPix * 3;
int count;
for (count=0;count<widthPix;count++)
{
BYTE iGray;
LPBYTE oRed, oBlu, oGrn;
// get our grayscale value
iGray = *(jpegline + count);
oRed = outBuf + offset + count * 3;
oGrn = outBuf + offset + count * 3 + 1;
oBlu = outBuf + offset + count * 3 + 2;
*oRed = iGray;
*oGrn = iGray;
*oBlu = iGray;
}
}
void j_putGrayScanline(BYTE *jpegline, int widthPix, BYTE *outBuf, int row)
{
int offset = row * widthPix;
int count;
for (count=0;count<widthPix;count++)
{
BYTE iGray;
LPBYTE oGray;
// get our grayscale value
iGray = *(jpegline + count);
oGray = outBuf + offset + count;
*oGray = iGray;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -