SIZE GetJPGEImagePiex(LPCTSTR szFileName)
{
SIZE sizePiex={0,0};
HANDLE hFile = INVALID_HANDLE_VALUE;
do
{
hFile = CreateFile(szFileName,
GENERIC_READ,
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
if(hFile == INVALID_HANDLE_VALUE)
{
DWORD dwErr = GetLastError();
_ASSERT(FALSE);
}
#pragma pack(push, 1)
struct _tagImgSection_t
{
BYTE SectionStart; //必须为0xFF
BYTE SectionID; //段标识
BYTE SectionLenH, SectionLenL; //段长度高8位//段长度低8位
}ImgSection;
#pragma pack(pop)
DWORD dwReaded = 0;
//图像头SOI标识
if((!ReadFile(hFile, &ImgSection, 2, &dwReaded, NULL))
|| (dwReaded != 2)
|| (ImgSection.SectionStart != 0xFF) //非标记
|| (ImgSection.SectionID != 0xD8)//非SOI起始头
|| 0)
{
_ASSERT(FALSE);
break;
}
BOOL bDone = FALSE;
while(! bDone)
{
memset(&ImgSection, 0, sizeof(ImgSection));
if((! ReadFile(hFile, &ImgSection, sizeof(ImgSection), &dwReaded, NULL))
|| (dwReaded != sizeof(ImgSection))
|| 0)
break; //读入出错
if(ImgSection.SectionStart != 0xFF) //非段标识标记
break;
switch(ImgSection.SectionID)
{
case(0xFF): //当前标识为数据
{
continue;
}
case(0xD9): // EOI,End of Image,图像结束
{
bDone = TRUE;
break;
}
case(0xC0): //SOF0,Start of Frame,帧图像开始
{
#pragma pack(push, 1) //结构体一个字节对齐
typedef struct _tagSOF0STRUCT_t
{
struct _tagHead_t
{
//BYTE wLenH, wLenL; //① 数据长度 2字节 ①~⑥六个字段的总长度
BYTE Sample_precision; //② 精度 1字节 每个数据样本的位数
BYTE HighPiexsH, HighPiexsL; //③ 图像高度 图像高度(单位:像素)
BYTE WidthPiexsH, WidthPiexsL; //④ 图像宽度 图像宽度(单位:像素)
BYTE ColorTabNums; // ⑤ 颜色分量数
}Head;
//而JFIF中使用YCrCb,故这里颜色分量数恒为3
struct _ColorTab
{ // ⑥颜色分量信息 颜色分量数×3字节(通常为9字节)
BYTE tabID; //a) 颜色分量ID 1字节
BYTE vSampFactor:4; //低4位:垂直采样因子
BYTE hSampFactory:4; //高4位:水平采样因子
BYTE curTabID; //当前分量使用的量化表的ID
}ColorTag[1];
}SOF0STRUCT;
#pragma pack(pop) //恢复结构体对齐长度
SOF0STRUCT sofoData = {0};
int headLen = sizeof(sofoData.Head);
if( (!ReadFile(hFile, &sofoData, headLen, &dwReaded, NULL))
|| dwReaded != sizeof(sofoData.Head))
break;
sizePiex.cx = MAKEWORD(sofoData.Head.WidthPiexsL, sofoData.Head.WidthPiexsH);
sizePiex.cy = MAKEWORD(sofoData.Head.HighPiexsL, sofoData.Head.HighPiexsH);
//后续的略……
bDone = TRUE;
break;
}
default:
{
LONG iSeek = (LONG)MAKEWORD(ImgSection.SectionLenL, ImgSection.SectionLenH) - 2;
SetFilePointer(hFile, iSeek, NULL, FILE_CURRENT);
break;
}
}
}
} while (0);
if(hFile != INVALID_HANDLE_VALUE)
{
CloseHandle(hFile);
}
return sizePiex;
}
//测试
CFileDialog fileDlg(TRUE);
if(fileDlg.DoModal() == IDOK)
{
SIZE imgPiex = GetJPGEImagePiex(fileDlg.GetPathName());
CString szMsg;
szMsg.Format(_T("%s\n(width=%d height=%d)"),
fileDlg.GetFileName(),
imgPiex.cx, imgPiex.cy);
AfxMessageBox(szMsg);
}