JpegModule.cpp
上传用户:yatsl7111
上传日期:2007-01-08
资源大小:1433k
文件大小:28k
- /********************************************************************
- JpegModule.cpp - ISee图像浏览器—JPEG图像读写模块实现文件
-
- 版权所有(C) 2000 VCHelp-coPathway-ISee workgroup member
- 这一程序是自由软件,你可以遵照自由软件基金会出版的GNU 通用公共许
- 可证条款来修改和重新发布这一程序。或者用许可证的第二版,或者(根
- 据你的选择)用任何更新的版本。
- 发布这一程序的目的是希望它有用,但没有任何担保。甚至没有适合特定
- 目地的隐含的担保。更详细的情况请参阅GNU通用公共许可证。
- 你应该已经和程序一起收到一份GNU通用公共许可证的副本。如果还没有,
- 写信给:
- The Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
- MA02139, USA
- 如果你在使用本软件时有什么问题或建议,用以下地址可以与我们取得联
- 系:
- http://isee.126.com
- http://www.vchelp.net
- 或:
- iseesoft@china.com
- 编写人:orbit
- E-Mail:Inte2000@263.net
- 文件版本:
- Beta 1.5
- Build 01209
- Date 2000-12-9
- ********************************************************************/
- #include "stdafx.h"
- #include "..publicgol_isee.h" // 此文件定义了接口数据包
- #include "JpegModule.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- static char ModuleProcessImgType[]="JPEG,JPG"; // 本模块能处理的图像类型
- static char WriterList[]="orbit"; // 本模块的作者列表
- static char WriterMess[]="死不了人的!"; // 作者留言
- //@@@@@@@@@@@@ YZ 于2000-12-9增加以下两行代码@@@@@@@@@@@@@
- static int RWPROGRESSSIZE;
- static const int RWPROGRESSSTEP = 10;
- //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- //
- // Note!
- //
- // If this DLL is dynamically linked against the MFC
- // DLLs, any functions exported from this DLL which
- // call into MFC must have the AFX_MANAGE_STATE macro
- // added at the very beginning of the function.
- //
- // For example:
- //
- // extern "C" BOOL PASCAL EXPORT ExportedFunction()
- // {
- // AFX_MANAGE_STATE(AfxGetStaticModuleState());
- // // normal function body here
- // }
- //
- // It is very important that this macro appear in each
- // function, prior to any calls into MFC. This means that
- // it must appear as the first statement within the
- // function, even before any object variable declarations
- // as their constructors may generate calls into the MFC
- // DLL.
- //
- // Please see MFC Technical Notes 33 and 58 for additional
- // details.
- //
- // 在图像读写模块中,如果想分配内存,请使用API函数GlobalAlloc()
- // ,如果想释放内存请使用GlobalFree()函数。不要使用诸如:new
- // 、malloc()等函数。这是为了使各模块之间可以异地释放内存。
- //
- //
- /////////////////////////////////////////////////////////////////////////////
- // CJpegModuleApp
- BEGIN_MESSAGE_MAP(CJpegModuleApp, CWinApp)
- //{{AFX_MSG_MAP(CJpegModuleApp)
- // NOTE - the ClassWizard will add and remove mapping macros here.
- // DO NOT EDIT what you see in these blocks of generated code!
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CJpegModuleApp construction
- CJpegModuleApp::CJpegModuleApp()
- {
- // TODO: add construction code here,
- // Place all significant initialization in InitInstance
- }
- /////////////////////////////////////////////////////////////////////////////
- // The one and only CJpegModuleApp object
- CJpegModuleApp theApp;
- // 接口函数声明 — 第一层,唯一与外界联系的接口
- int WINAPI AccessJPEGModule(INFOSTR *pInfo)
- {
- // 这个函数可以不作修改的使用,除非你的返回值多于两种。
- switch(pInfo->comm)
- {
- case CMD_GETPROCTYPE: // 获取本模块能处理的图像类型
- _fnCMD_GETPROCTYPE(pInfo);
- break;
- case CMD_GETWRITERS: // 获取本模块的作者列表,多人时用逗号分隔
- _fnCMD_GETWRITERS(pInfo);
- break;
- case CMD_GETWRITERMESS: // 获取作者们的留言
- _fnCMD_GETWRITERMESS(pInfo);
- break;
- case CMD_GETBUILDID: // 获取图像模块内部版本号
- _fnCMD_GETBUILDID(pInfo);
- break;
- case CMD_IS_VALID_FILE: // 判断指定文件是否是有效的WMF文件
- _fnCMD_IS_VALID_FILE(pInfo);
- break;
- case CMD_GET_FILE_INFO: // 获取指定文件的信息
- _fnCMD_GET_FILE_INFO(pInfo);
- break;
- case CMD_LOAD_FROM_FILE: // 从指定图像文件中读取数据
- _fnCMD_LOAD_FROM_FILE(pInfo);
- break;
- case CMD_SAVE_TO_FILE: // 将数据保存到指定文件中
- _fnCMD_SAVE_TO_FILE(pInfo);
- break;
- case CMD_IS_SUPPORT: // 查询某个命令是否被支持
- _fnCMD_IS_SUPPORT(pInfo);
- break;
- case CMD_RESIZE: // 从新获取指定尺寸的图像位数据(只适用于矢量图像)
- _fnCMD_RESIZE(pInfo);
- break;
- default:
- pInfo->result = ER_ILLCOMM; // 非法命令
- ASSERT(FALSE); // 调用者的程序设计有问题 :-)
- break;
- }
- // 执行命令成功返回1, 失败返回0
- return (pInfo->result==ER_SUCCESS)? 1:0;
- }
- // 命令解释函数 — 第二层解释函数
- //********************************************************************//
- // 操作命令解释函数---解释:CMD_IS_SUPPORT命令
- // 查询某个命令是否被支持
- void _fnCMD_IS_SUPPORT(INFOSTR *pInfo)
- {
- // 这个函数是为客户程序查询时使用,如果你实现了对某个命令的
- // 解释,可修改相应的case中的设置,使其返回ER_SUCCESS,这就
- // 表示你的模块已经支持该命令了。同时,现在的这个文件中已包
- // 含了对前四个命令的解释,你只需向还未支持的命令函数中添加
- // 代码即可。
- ASSERT(pInfo->result == ER_EMPTY);
- switch(pInfo->annexdata.cmAnnData)
- {
- case CMD_GETPROCTYPE: // 获取本模块能处理的图像类型
- pInfo->result = ER_SUCCESS;
- break;
- case CMD_GETWRITERS: // 获取本模块的作者列表,多人时用逗号分隔
- pInfo->result = ER_SUCCESS;
- break;
- case CMD_GETWRITERMESS: // 获取作者们的留言
- pInfo->result = ER_SUCCESS;
- break;
- case CMD_GETBUILDID: // 获取图像模块内部版本号
- pInfo->result = ER_SUCCESS;
- break;
- case CMD_IS_VALID_FILE: // 判断指定文件是否是有效的WMF文件
- pInfo->result = ER_SUCCESS;
- break;
- case CMD_GET_FILE_INFO: // 获取指定文件的信息
- pInfo->result = ER_SUCCESS;
- break;
- case CMD_LOAD_FROM_FILE: // 从指定图像文件中读取数据
- pInfo->result = ER_SUCCESS;
- break;
- case CMD_SAVE_TO_FILE: // 将数据保存到指定文件中
- pInfo->result = ER_SUCCESS;
- break;
- case CMD_IS_SUPPORT: // 查询某个命令是否被支持
- pInfo->result = ER_SUCCESS;
- break;
- case CMD_RESIZE: // 获取指定尺寸的图像(只适用于矢量图像)
- pInfo->result = ER_NOTSUPPORT;
- break;
- default:
- pInfo->result = ER_NOTSUPPORT;
- break;
- }
- }
- // 操作命令解释函数---解释:CMD_GETPROCTYPE命令
- // 获取本模块能处理的图像类型,如:BMP,PCX等等
- void _fnCMD_GETPROCTYPE(INFOSTR *pInfo)
- {
- // 这是预定义的函数代码,你可以不必修改的使用。
- // 根据接口定义,此时附加数据应被清空为0,所以下此断言
- ASSERT(pInfo->annexdata.scAnnData[0] == 0);
- ASSERT(pInfo->result == ER_EMPTY);
- // 复制能处理的类型字符串
- ::CopyMemory((PVOID)pInfo->annexdata.scAnnData, (PVOID)ModuleProcessImgType,
- sizeof(ModuleProcessImgType));
- pInfo->result = ER_SUCCESS;
- }
- // 操作命令解释函数---解释:CMD_GETWRITER命令
- // 获取本模块的作者列表,多人时用逗号分隔
- void _fnCMD_GETWRITERS(INFOSTR *pInfo)
- {
- // 这是预定义的函数代码,你可以不必修改的使用。
- // 根据接口定义,此时附加数据应被清空为0,所以下此断言
- ASSERT(pInfo->annexdata.scAnnData[0] == 0);
- ASSERT(pInfo->result == ER_EMPTY);
- // 复制开发者名单串
- ::CopyMemory((PVOID)pInfo->annexdata.scAnnData, (PVOID)WriterList,
- sizeof(WriterList));
- pInfo->result = ER_SUCCESS;
- }
- // 操作命令解释函数---解释:CMD_GETWRITERMESS命令
- // 获取作者们的留言
- void _fnCMD_GETWRITERMESS(INFOSTR *pInfo)
- {
- // 这是预定义的函数代码,你可以不必修改的使用。
- // 根据接口定义,此时附加数据应被清空为0,所以下此断言
- ASSERT(pInfo->annexdata.scAnnData[0] == 0);
- ASSERT(pInfo->result == ER_EMPTY);
- // 复制开发者们的留言字符串
- ::CopyMemory((PVOID)pInfo->annexdata.scAnnData, (PVOID)WriterMess,
- sizeof(WriterMess));
- pInfo->result = ER_SUCCESS;
- }
- // 操作命令解释函数---解释:CMD_GETBUILDID命令
- // 获取图像模块内部版本号
- void _fnCMD_GETBUILDID(INFOSTR *pInfo)
- {
- // 这是预定义的函数代码,你可以不必修改的使用。
- // 根据接口定义,此时annexdata.dwAnnData应被设为0,所以下此断言
- ASSERT(pInfo->annexdata.dwAnnData == 0);
- ASSERT(pInfo->result == ER_EMPTY);
- // 填写内部版本号码
- pInfo->annexdata.dwAnnData = MODULE_BUILDID;
- pInfo->result = ER_SUCCESS;
- }
- // 操作命令解释函数---解释:CMD_IS_VALID_FILE命令
- // 判断指定文件是否是有效的JPG文件
- void _fnCMD_IS_VALID_FILE(INFOSTR *pInfo)
- {
- ASSERT(pInfo);
- ASSERT(pInfo->result == ER_EMPTY);
- ASSERT(pInfo->annexdata.iAnnData == 0);
- ASSERT(::strlen(pInfo->filename));
- ASSERT(pInfo->state == PKST_NOTVER);
- WORD wMarker;
- HANDLE hFile;
- pInfo->result = ER_SUCCESS;
- pInfo->annexdata.iAnnData = 0;
- hFile = ::CreateFile(pInfo->filename, GENERIC_READ, FILE_SHARE_READ, NULL,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if(hFile == INVALID_HANDLE_VALUE)
- pInfo->result = ER_COMMINFOERR; //文件打开错
- else
- {
- DWORD dwBytes;
- BOOL Correct = ::ReadFile(hFile, &wMarker, 2, &dwBytes, NULL);
- if(!Correct)
- {
- pInfo->result = ER_FILERWERR;
- TRACE("JPEG-读文件错误!");
- ::CloseHandle(hFile);
- return;
- }
- if(!CHECK_JPG_SOI(wMarker))
- pInfo->annexdata.iAnnData = 0;
- else
- {
- pInfo->annexdata.iAnnData = 1;
- pInfo->state = PKST_PASSVER;
- }
- CloseHandle(hFile);
- }
- }
- // 操作命令解释函数---解释:CMD_GET_FILE_INFO命令
- // 获取指定文件的信息
- void _fnCMD_GET_FILE_INFO(INFOSTR *pInfo)
- {
- // 检验入口参数是否符合接口定义
- ASSERT(pInfo->result == ER_EMPTY);
- ASSERT(::strlen(pInfo->filename));
- ASSERT(pInfo->state == PKST_PASSVER);
- ASSERT(pInfo->imginfo.imgtype == IMT_NULL);
- struct jpeg_decompress_struct cinfo;
- struct my_error_mgr jerr;
- FILE * infile=NULL;
- if ((infile = fopen(pInfo->filename, "rb")) == NULL)
- {
- pInfo->result = ER_FILERWERR;
- return;
- }
- cinfo.err = jpeg_std_error(&jerr.pub);
- jerr.pub.error_exit = my_error_exit;
- if (setjmp(jerr.setjmp_buffer))
- {
- //如果代码执行到这里就说明JPEG解码出现错误
- jpeg_destroy_decompress(&cinfo);
- if (infile!=NULL)
- fclose(infile);
- pInfo->result = ER_BADIMAGE;
- return;
- }
- jpeg_create_decompress(&cinfo);
- jpeg_stdio_src(&cinfo, infile);
- jpeg_read_header(&cinfo, TRUE);
-
- fseek(infile,0,SEEK_END);
- DWORD dwSize = ftell(infile);
- fseek(infile,0,SEEK_SET);
-
- // jpeg_finish_decompress(&cinfo);
- jpeg_destroy_decompress(&cinfo);
- fclose(infile);
- LPIMAGEINFOSTR lpImgInfoStr = &pInfo->imginfo;
- lpImgInfoStr->imgtype = IMT_RESSTATIC;
- lpImgInfoStr->imgformat = IMF_JPEG;
- lpImgInfoStr->filesize = dwSize;
- lpImgInfoStr->width = cinfo.image_width;
- lpImgInfoStr->height = cinfo.image_height;
- lpImgInfoStr->bitcount = DWORD((cinfo.num_components == 3) ? 24 : 8);
- lpImgInfoStr->compression = CompressType(cinfo.jpeg_color_space);
- lpImgInfoStr->linesize = DIBSCANLINE_WIDTHBYTES(lpImgInfoStr->width*lpImgInfoStr->bitcount);
- lpImgInfoStr->imgnumbers = 1;
- lpImgInfoStr->imgchang = 0;
- HANDLE hFile;
- FILETIME fLWT;
- SYSTEMTIME sLWT;
- hFile = ::CreateFile(pInfo->filename, GENERIC_READ, FILE_SHARE_READ, NULL,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if(::GetFileTime(hFile, NULL, NULL, &fLWT))
- {
- ::CloseHandle(hFile);
- FileTimeToSystemTime(&fLWT, &sLWT);
- lpImgInfoStr->year = sLWT.wYear;
- lpImgInfoStr->monday = sLWT.wMonth;
- lpImgInfoStr->monday <<= 8;
- lpImgInfoStr->monday |= sLWT.wDay;
-
- lpImgInfoStr->time = sLWT.wHour;
- lpImgInfoStr->time <<= 8;
- lpImgInfoStr->time |= sLWT.wMinute;
- lpImgInfoStr->time <<= 8;
- lpImgInfoStr->time |= sLWT.wSecond;
- lpImgInfoStr->time &= 0xffffff;
- pInfo->state = PKST_PASSINFO;
- pInfo->result = ER_SUCCESS;
- }
- else
- pInfo->result = ER_FILERWERR;
- }
- // 操作命令解释函数---解释:CMD_LOAD_FROM_FILE命令
- // 从指定图像文件中读取数据
- void _fnCMD_LOAD_FROM_FILE(INFOSTR *pInfo)
- {
- ASSERT(pInfo->result == ER_EMPTY);
- ASSERT(::strlen(pInfo->filename));
- ASSERT(pInfo->state == PKST_PASSINFO);
- ASSERT(pInfo->imginfo.imgformat == IMF_JPEG);
- ASSERT(pInfo->pImgInfo == NULL);
- ASSERT(pInfo->sDIBInfo.bmi.biSize == sizeof(BITMAPINFOHEADER));
- ASSERT(pInfo->pLineAddr != NULL);
- ASSERT(pInfo->_pbdata != NULL);
-
- struct jpeg_decompress_struct cinfo;
- struct my_error_mgr jerr;
- FILE * infile=NULL;
- JSAMPARRAY buffer;
- int row_stride;
- //@@@@@@@@@@@@@@@@@ YZ 于2000-12-9增加以下代码@@@@@@@@@@@@
- // 以图像的高度值作为进度总值
- RWPROGRESSSIZE = (int)pInfo->imginfo.height;
- //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- if (pInfo->fpProgress)
- {
- if ((*pInfo->fpProgress)(RWPROGRESSSIZE, 0))
- { // 如果进度函数返回1,则说明用户想中断操作,返回。
- pInfo->result = ER_USERBREAK;
- return;
- }
- }
- if ((infile = fopen(pInfo->filename, "rb")) == NULL)
- {
- pInfo->result = ER_FILERWERR;
- return;
- }
- cinfo.err = jpeg_std_error(&jerr.pub);
- jerr.pub.error_exit = my_error_exit;
- if (setjmp(jerr.setjmp_buffer))
- {
- //如果代码执行到这里就说明JPEG解码出现错误
- jpeg_destroy_decompress(&cinfo);
- if (infile!=NULL)
- fclose(infile);
- pInfo->result = ER_BADIMAGE;
- return;
- }
- jpeg_create_decompress(&cinfo);
- jpeg_stdio_src(&cinfo, infile);
- jpeg_read_header(&cinfo, TRUE);
- jpeg_start_decompress(&cinfo);
-
- row_stride = cinfo.output_width * cinfo.output_components;
- buffer = (*cinfo.mem->alloc_sarray)
- ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
- LPBYTE pData;
- BYTE red, green, blue,gray;
- DWORD widthCount;
- //JPEG只支持两种格式的图象
- if (cinfo.out_color_components == 3)//24位彩色图象
- {
- while (cinfo.output_scanline < cinfo.output_height)
- {
- jpeg_read_scanlines(&cinfo, buffer, 1);
- pData = buffer[0];
- //@@@@@@@@@@@@@@@@@ YZ 于2000-12-9修改以下代码@@@@@@@@@@@@
- /*
- if(pInfo->fpProgress)
- {
- if ((*pInfo->fpProgress)(RWPROGRESSSIZE, cinfo.output_scanline * 100 / cinfo.output_height))
- {
- pInfo->result = ER_USERBREAK;
- return ;
- }
- }
- */
- // 为:
- if ((pInfo->fpProgress)&&(!(cinfo.output_scanline%RWPROGRESSSTEP)))
- {
- if ((*pInfo->fpProgress)(RWPROGRESSSIZE, cinfo.output_scanline))
- {
- pInfo->result = ER_USERBREAK;
- jpeg_destroy_decompress(&cinfo);
- fclose(infile);
- return ; // 用户中断操作
- }
- }
- //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- switch(_get_desformat(pInfo)) // 标准图像格式(目标格式)
- {
- case DF_16_555:
- {
- WORD *pDesPixAddr555 = (WORD*)pInfo->pLineAddr[cinfo.output_scanline - 1];
- for (widthCount=0;widthCount<cinfo.output_width;widthCount++)
- {
- red = *pData++;
- green = *pData++;
- blue = *pData++;
- *pDesPixAddr555++ = WORD((((WORD)red>>3)<<10)|(((WORD)green>>3)<<5)|((WORD)blue>>3));
- }
- }
- break;
- case DF_16_565:
- {
- WORD *pDesPixAddr565 = (WORD*)pInfo->pLineAddr[cinfo.output_scanline - 1];
- for (widthCount=0;widthCount<cinfo.output_width;widthCount++)
- {
- red = *pData++;
- green = *pData++;
- blue = *pData++;
- *pDesPixAddr565++ = WORD((((WORD)red>>3)<<11)|(((WORD)green>>2)<<5)|((WORD)blue>>3));
- }
- }
- break;
- case DF_24:
- ::CopyMemory((PVOID)pInfo->pLineAddr[cinfo.output_scanline - 1], (PVOID)pData, cinfo.output_width * 3);
- break;
- case DF_32:
- {
- DWORD *pDesPixAddr888;
- DWORD pix32;
- pDesPixAddr888 = (DWORD*)pInfo->pLineAddr[cinfo.output_scanline - 1];// 目标缓冲区当前行第一个像素的地址
- for (widthCount=0;widthCount<cinfo.output_width;widthCount++)
- {
- red = *pData++;
- green = *pData++;
- blue = *pData++;
- pix32 = DWORD(((DWORD)red<<16)|((DWORD)green<<8)|(DWORD)blue);
- pix32 &= 0x00FFFFFF;
- *pDesPixAddr888++ = pix32;
- }
- }
- break;
- case DF_NULL:
- default:
- ASSERT(FALSE);
- pInfo->result = ER_ILLCOMM;
- jpeg_finish_decompress(&cinfo);
- jpeg_destroy_decompress(&cinfo);
- fclose(infile);
- return;
- break;
- }
- }
- pInfo->state = PKST_INFOANDBITS;
- pInfo->result = ER_SUCCESS;
- }
- else if(cinfo.out_color_components == 1)//256级灰度图象
- {
- while (cinfo.output_scanline < cinfo.output_height)
- {
- jpeg_read_scanlines(&cinfo, buffer, 1);
- pData = buffer[0];
- //@@@@@@@@@@@@@@@@@ YZ 于2000-12-9修改以下代码@@@@@@@@@@@@
- /*
- if(pInfo->fpProgress)
- {
- if ((*pInfo->fpProgress)(RWPROGRESSSIZE, cinfo.output_scanline * 100 / cinfo.output_height))
- {
- pInfo->result = ER_USERBREAK;
- return ;
- }
- }
- */
- // 为:
- if ((pInfo->fpProgress)&&(!(cinfo.output_scanline%RWPROGRESSSTEP)))
- {
- if ((*pInfo->fpProgress)(RWPROGRESSSIZE, cinfo.output_scanline))
- {
- pInfo->result = ER_USERBREAK;
- jpeg_destroy_decompress(&cinfo);
- fclose(infile);
- return ; // 用户中断操作
- }
- }
- //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- switch(_get_desformat(pInfo)) // 标准图像格式(目标格式)
- {
- case DF_16_555:
- {
- WORD *pDesPixAddr555 = (WORD*)pInfo->pLineAddr[cinfo.output_scanline - 1];
- for (widthCount=0;widthCount<cinfo.output_width;widthCount++)
- {
- gray = *pData++;
- *pDesPixAddr555++ = WORD((((WORD)gray>>3)<<10)|(((WORD)gray>>3)<<5)|((WORD)gray>>3));
- }
- }
- break;
- case DF_16_565:
- {
- WORD *pDesPixAddr565 = (WORD*)pInfo->pLineAddr[cinfo.output_scanline - 1];
- for (widthCount=0;widthCount<cinfo.output_width;widthCount++)
- {
- gray = *pData++;
- *pDesPixAddr565++ = WORD((((WORD)gray>>3)<<11)|(((WORD)gray>>2)<<5)|((WORD)gray>>3));
- }
- }
- break;
- case DF_24:
- {
- LPBYTE lpdes = (LPBYTE)pInfo->pLineAddr[cinfo.output_scanline - 1];
- for (widthCount=0;widthCount<cinfo.output_width;widthCount++)
- {
- gray = *pData++;
- *lpdes++ = gray;
- *lpdes++ = gray;
- *lpdes++ = gray;
- }
- }
- break;
- case DF_32:
- {
- DWORD *pDesPixAddr888;
- DWORD pix32;
- pDesPixAddr888 = (DWORD*)pInfo->pLineAddr[cinfo.output_scanline - 1];// 目标缓冲区当前行第一个像素的地址
- for (widthCount=0;widthCount<cinfo.output_width;widthCount++)
- {
- gray = *pData++;
- pix32 = DWORD(((DWORD)gray<<16)|((DWORD)gray<<8)|(DWORD)gray);
- pix32 &= 0x00FFFFFF;
- *pDesPixAddr888++ = pix32;
- }
- }
- break;
- case DF_NULL:
- default:
- ASSERT(FALSE);
- pInfo->result = ER_ILLCOMM;
- jpeg_finish_decompress(&cinfo);
- jpeg_destroy_decompress(&cinfo);
- fclose(infile);
- return;
- break;
- }
- }
-
- pInfo->state = PKST_INFOANDBITS;
- pInfo->result = ER_SUCCESS;
- }
- else
- {
- pInfo->result = ER_BADIMAGE;
- }
- jpeg_finish_decompress(&cinfo);
- jpeg_destroy_decompress(&cinfo);
- fclose(infile);
- //@@@@@@@@@@@@@@@@@ YZ 于2000-12-9增加以下代码@@@@@@@@@@@@
- if (pInfo->fpProgress)
- (*pInfo->fpProgress)(RWPROGRESSSIZE, RWPROGRESSSIZE);
- //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- }
- // 操作命令解释函数---解释:CMD_SAVE_TO_FILE命令
- // 将数据保存到指定文件中
- void _fnCMD_SAVE_TO_FILE(INFOSTR *pInfo)
- {
- ASSERT(pInfo->result == ER_EMPTY);
- ASSERT(::strlen(pInfo->filename));
- ASSERT(pInfo->state == PKST_INFOANDBITS);
- ASSERT(pInfo->sDIBInfo.bmi.biSize == sizeof(BITMAPINFOHEADER));
- ASSERT(pInfo->pLineAddr != NULL);
- ASSERT(pInfo->_pbdata != NULL);
- FILE *outfile;
- UINT width,height;
- struct jpeg_compress_struct cinfo;
- int row_stride; /* physical row widthPix in image buffer */
- struct my_error_mgr jerr;
- LPBYTE lpDataBuf = NULL;
- LPIMAGEINFOSTR lpImgInfoStr = &pInfo->imginfo;
- //JPEG仅支持8、24位位图
- if(lpImgInfoStr->bitcount == 1 || lpImgInfoStr->bitcount == 4 ||
- lpImgInfoStr->bitcount == 16 || lpImgInfoStr->bitcount == 32)
- {
- pInfo->result = ER_NOTSUPPORT;
- return;
- }
- width = lpImgInfoStr->width;
- height = lpImgInfoStr->height;
- //@@@@@@@@@@@@@@@@@ YZ 于2000-12-9增加以下代码@@@@@@@@@@@@
- // 此时imginfo中的数据可能与sDIBInfo不一样,以sDIBInfo为准
- RWPROGRESSSIZE = (int)::abs(pInfo->sDIBInfo.bmi.biHeight);
- //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- if (pInfo->fpProgress)
- {
- if ((*pInfo->fpProgress)(RWPROGRESSSIZE, 0))
- {
- pInfo->result = ER_USERBREAK;
- return;
- }
- }
- if ((outfile = fopen((LPCTSTR)lpImgInfoStr->filename, "wb")) == NULL)
- {
- pInfo->result = ER_FILERWERR;
- return;
- }
- cinfo.err = jpeg_std_error(&jerr.pub);
- jerr.pub.error_exit = my_error_exit;
- if (setjmp(jerr.setjmp_buffer))
- {
- jpeg_destroy_compress(&cinfo);
- if (outfile!=NULL)
- fclose(outfile);
- //@@@@@@@@@@@@@@@@@ YZ 于2000-12-9删除以下代码@@@@@@@@@@@@
- // 因为该变量在此之前是NULL
- /*
- if(lpDataBuf != NULL)
- delete [] lpDataBuf;
- */
- //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- pInfo->result = ER_BADIMAGE;
- return;
- }
-
- jpeg_create_compress(&cinfo);
- jpeg_stdio_dest(&cinfo, outfile);
- cinfo.image_width = width;
- cinfo.image_height = height;
- if(lpImgInfoStr->bitcount == 24)
- {
- lpDataBuf = new BYTE[width * height * 3];
- if(lpDataBuf == NULL)
- {
- pInfo->result = ER_MEMORYERR;
- jpeg_destroy_compress(&cinfo);
- if (outfile!=NULL)
- fclose(outfile);
- return;
- }
- GetRGBBuf(pInfo,lpDataBuf);
- cinfo.input_components = 3;
- cinfo.in_color_space = JCS_RGB;
- }
- else if(lpImgInfoStr->bitcount == 8)
- {
- lpDataBuf = new BYTE[width * height];
- if(lpDataBuf == NULL)
- {
- pInfo->result = ER_MEMORYERR;
- jpeg_destroy_compress(&cinfo);
- if (outfile!=NULL)
- fclose(outfile);
- return;
- }
- GetGRAYBuf(pInfo,lpDataBuf);
- cinfo.input_components = 1;
- cinfo.in_color_space = JCS_GRAYSCALE;
- }
-
- jpeg_set_defaults(&cinfo);
- jpeg_set_quality(&cinfo, lpImgInfoStr->qualtify, TRUE);
- jpeg_start_compress(&cinfo, TRUE);
- row_stride = width * 3;
- LPBYTE outRow;
- if(lpImgInfoStr->bitcount == 24)
- {
- while (cinfo.next_scanline < cinfo.image_height)
- {
- outRow = lpDataBuf + (cinfo.next_scanline * width * 3);
- jpeg_write_scanlines(&cinfo, &outRow, 1);
- //@@@@@@@@@@@@@@@@@ YZ 于2000-12-9修改以下代码@@@@@@@@@@@@
- //为了编码的速度,所以又注释掉了,orbit,2000-08-31
- /*
- if(pInfo->fpProgress)
- {
- if ((*pInfo->fpProgress)(RWPROGRESSSIZE, cinfo.next_scanline * 100 / cinfo.image_height))
- {
- pInfo->result = ER_USERBREAK;
- return;
- }
- }
- */
- // 为:
- if ((pInfo->fpProgress)&&(!(cinfo.next_scanline%RWPROGRESSSTEP)))
- {
- if ((*pInfo->fpProgress)(RWPROGRESSSIZE, cinfo.next_scanline))
- {
- pInfo->result = ER_USERBREAK;
- jpeg_destroy_compress(&cinfo);
- delete [] lpDataBuf;
- fclose(outfile);
- return ; // 用户中断操作
- }
- }
- //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- }
- }
- else if(lpImgInfoStr->bitcount == 8)
- {
- while (cinfo.next_scanline < cinfo.image_height)
- {
- outRow = lpDataBuf + (cinfo.next_scanline * width);
- jpeg_write_scanlines(&cinfo, &outRow, 1);
- //@@@@@@@@@@@@@@@@@ YZ 于2000-12-9修改以下代码@@@@@@@@@@@@
- //为了编码的速度,所以又注释掉了,orbit,2000-08-31
- /*
- if(pInfo->fpProgress)
- {
- if ((*pInfo->fpProgress)(RWPROGRESSSIZE, cinfo.next_scanline * 100 / cinfo.image_height))
- {
- pInfo->result = ER_USERBREAK;
- return;
- }
- }
- */
- // 为:
- if ((pInfo->fpProgress)&&(!(cinfo.next_scanline%RWPROGRESSSTEP)))
- {
- if ((*pInfo->fpProgress)(RWPROGRESSSIZE, cinfo.next_scanline))
- {
- pInfo->result = ER_USERBREAK;
- jpeg_destroy_compress(&cinfo);
- delete [] lpDataBuf;
- fclose(outfile);
- return ; // 用户中断操作
- }
- }
- //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- }
- }
-
- jpeg_finish_compress(&cinfo);
- fclose(outfile);
- jpeg_destroy_compress(&cinfo);
- delete [] lpDataBuf;
-
- if (pInfo->fpProgress)
- (*pInfo->fpProgress)(RWPROGRESSSIZE, RWPROGRESSSIZE);
- pInfo->result = ER_SUCCESS;
- }
- // 操作命令解释函数---解释:CMD_RESIZE命令
- // 重新获取指定尺寸的图像位数据(只适用于矢量图像)
- void _fnCMD_RESIZE(INFOSTR *pInfo)
- {
- // 这个命令一般的图像读写模块不需要支持,它只适用于矢量图像,
- // 比如WMF、EMF之类。
- // 如果你想解释该命令,请在下面加入代码,并修改pInfo->result的返回值:
- // ----------------------------------------------------------------->
- pInfo->result = ER_NOTSUPPORT;
- }
- DESFORMAT _get_desformat(LPINFOSTR pInfo)
- {
- ASSERT(pInfo);
- // ASSERT(pInfo->state >= PKST_PASSVER);
- ASSERT(pInfo->sDIBInfo.bmi.biPlanes == 1);
- DESFORMAT result;
- switch(pInfo->sDIBInfo.bmi.biBitCount)
- {
- case 32:
- /******************************************************
- 32位掩码示意图
- 高 -> 低
- 0000 0000 0000 0000 0000 0000 0000 0000 888格式
- 1111 1111 ------------------------R
- 1111 1111 -------------G
- 1111 1111--B
- * Win95 系统只支持这一种格式
- ******************************************************/
- if (pInfo->sDIBInfo.bmi.biCompression == BI_RGB)
- {
- result = DF_32;
- break;
- }
- if ((pInfo->sDIBInfo.rmask == 0xff0000)&&
- (pInfo->sDIBInfo.gmask == 0xff00)&&
- (pInfo->sDIBInfo.bmask == 0xff))
- result = DF_32;
- else
- {
- ASSERT(FALSE); // 只支持888格式
- result = DF_NULL;
- }
- break;
- case 24:
- result = DF_24;
- break;
- case 16:
- /*******************************************
- 16位掩码示意图
- 高字节 低字节
- 0000 0000 0000 0000
- 1 1111--B // 555格式
- 11 111 -------G
- 111 11 --------------R
- 0
- 1 1111--B // 565格式
- 111 111 -------G
- 1111 1 --------------R
- * Win95 系统只支持以上两种格式
- *******************************************/
- if (pInfo->sDIBInfo.bmi.biCompression == BI_RGB)
- {
- result = DF_16_555;
- break;
- }
- if ((pInfo->sDIBInfo.rmask == 0x7c00)&&
- (pInfo->sDIBInfo.gmask == 0x3e0)&&
- (pInfo->sDIBInfo.bmask == 0x1f))
- result = DF_16_555;
- else if ((pInfo->sDIBInfo.rmask == 0xf800)&&
- (pInfo->sDIBInfo.gmask == 0x7e0)&&
- (pInfo->sDIBInfo.bmask == 0x1f))
- result = DF_16_565;
- else
- result = DF_NULL;
- break;
- default:
- ASSERT(FALSE); // 不接受其它格式
- result = DF_NULL;
- break;
- }
- return result;
- }
- IMGCOMPRESS CompressType(J_COLOR_SPACE jcs)
- {
- IMGCOMPRESS rtn = ICS_MAX;
- switch(jcs)
- {
- case JCS_UNKNOWN:
- rtn = ICS_MAX;
- break;
- case JCS_GRAYSCALE:
- rtn = ICS_JPEGGRAYSCALE;
- break;
- case JCS_RGB:
- rtn = ICS_JPEGRGB;
- break;
- case JCS_YCbCr:
- rtn = ICS_JPEGYCbCr;
- break;
- case JCS_CMYK:
- rtn = ICS_JPEGCMYK;
- break;
- case JCS_YCCK:
- rtn = ICS_JPEGYCCK;
- break;
- default:
- break;
- }
- return rtn;
- }
- METHODDEF(void) my_error_exit (j_common_ptr cinfo)
- {
- my_error_ptr myerr = (my_error_ptr) cinfo->err;
- char buffer[JMSG_LENGTH_MAX];
- (*cinfo->err->format_message) (cinfo, buffer);
- // 此行被注释掉,以免破坏调用者界面。YZ 2000-11-15日
- // MessageBox(NULL,buffer,"JPEG Fatal Error",MB_ICONSTOP);
- longjmp(myerr->setjmp_buffer, 1);
- }
- ////////////////////////////////////////////////////////////////////////////////
- //将pInfo的数据转化为编码所用的格式(24位RGB格式)
- //lpRBGBuf---数据缓冲区,大小为:width*height*3 Bytes
- //orbit,2000-08-31
- ////////////////////////////////////////////////////////////////////////////////
- BOOL GetRGBBuf(LPINFOSTR pInfo,LPBYTE lpRBGBuf)
- {
- BITMAPINFOHEADER bmpInfo = pInfo->sDIBInfo.bmi;
- if(bmpInfo.biBitCount != 32)
- return FALSE;
- DWORD hei = bmpInfo.biHeight;
- DWORD wid = bmpInfo.biWidth;
- LPBYTE lp = lpRBGBuf,lpRow;
- for(DWORD row = hei - 1; row >= 1; row--)
- {
- lpRow = (LPBYTE)pInfo->pLineAddr[row];
- for(DWORD i = 0; i < wid; i++)
- {
- *lp++ = *(lpRow + 3); //red
- *lp++ = *(lpRow + 2); //green
- *lp++ = *(lpRow + 1); //blue
- lpRow += 4;
- }
- }
- return TRUE;
- }
- ////////////////////////////////////////////////////////////////////////////////
- //将pInfo的数据转化为编码所用的格式(8位灰度格式)
- //lpGRAYBuf---数据缓冲区,大小为:width*height Bytes
- //orbit,2000-08-31
- ////////////////////////////////////////////////////////////////////////////////
- BOOL GetGRAYBuf(LPINFOSTR pInfo,LPBYTE lpGRAYBuf)
- {
- BITMAPINFOHEADER bmpInfo = pInfo->sDIBInfo.bmi;
-
- if(bmpInfo.biBitCount != 32)
- return FALSE;
- DWORD hei = bmpInfo.biHeight;
- DWORD wid = bmpInfo.biWidth;
- LPBYTE lp = lpGRAYBuf,lpRow;
- BYTE red,blue,green;
- int tmp;
- for(DWORD row = hei - 1; row >= 1; row-- )
- {
- lpRow = (LPBYTE)pInfo->pLineAddr[row];
- for(DWORD i = 0; i < wid; i++)
- {
- red = *(lpRow + 3); //red
- green = *(lpRow + 2); //green
- blue = *(lpRow + 1); //blue
- tmp = (int)(.299 * (double)(red) + .587 * (double)(green) + .114 * (double)(blue));
- *lp++ = (BYTE)tmp;
- lpRow += 4;
- }
- }
- return TRUE;
- }