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

📄 jpeg.cpp

📁 将JPEG图像解压为BMP图像。 内含图像处理的一些基本函数。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
}

//////////////////////////////////////////////////////////////
//
//  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 + -