IMAGE_TIF (=1) 是我自己定义的,因为我的软件还能处理bmp.
#define tagNewSubfileType 254
#define tagSubfileType 255
#define tagImageWidth 256
#define tagImageLength 257
#define tagBitsPerSample 258
#define tagCompression 259
#define tagPhotometricInterp 262
#define tagThreshholding 263
#define tagCellWidth 264
#define tagCellLength 265
#define tagFillOrder 266
#define tagMake 271
#define tagModel 272
#define tagStripOffsets 273
#define tagOrientation 274
#define tagSamplesPerPixel 277
#define tagRowsPerStrip 278
#define tagStripByteCounts 279
#define tagMinSamplue 280
#define tagMaxSamplue 281
#define tagXResolution 282
#define tagYResolution 283
#define tagPlanarConfiguration 284
#define tagPageName 285
#define tagXPosition 286
#define tagYPosition 287
#define tagFreeOffsets 288
#define tagFreeByteCounts 289
#define tagGrayResponseUnit 290
#define tagGrayResponseCurve 291
#define tagGroup3Options 292
#define tagGroup4Options 293
#define tagResolutionUnit 296
#define tagPageNumber 297
#define tagColorResponseUnit 300
#define tagColorResponseCurves 301
#define tagPredictor 317
#define tagColorMap 320
#define TIFFbyte 1
#define TIFFascii 2
#define TIFFshort 3
#define TIFFlong 4
#define TIFFrational 5
#define COMPnone 1
#define COMPhuff 2
#define COMPfax3 3
#define COMPfax4 4
#define COMPlzw 5
#define COMPwrd1 0x8003
#define COMPmpnt 0x8005
typedef struct
{
WORD ByteOrder;
WORD Version;
DWORD IFDOffset;
} TIFHEADER;
typedef TIFHEADER *PTIFHEADER;
typedef struct
{
WORD TifTag;
WORD DataType;
DWORD DataLength;
DWORD ulData;
} IFDITEM;
typedef IFDITEM *PIFDITEM;
#define UNIT_none 1
#define UNIT_inch 2
#define UNIT_cm 3
class CTifImage : public CImage
{
public:
DWORD m_PhotometricInterpretatio n; // 0:invert,1:normal
DWORD m_RowsPerStrip;
DWORD m_StripCount; //must be 1
DWORD m_BytesPerStrip;
DWORD m_Predictor; //must be 1-No Predictor
DWORD m_SamplesPerPixel;
DWORD m_BitsPerSample;
public:
CTifImage();
virtual ~CTifImage();
public:
virtual BOOL ImageNegative();
virtual DWORD OpenImage(char *pFileName);
virtual DWORD GetImageLine(char *pBuf,DWORD LineIndex,DWORD LineCnt);
virtual DWORD DeviceCompatible();
private:
void InitMemberVars();
};
DWORD CTifImage::GetImageLine(char * pBuf, DWORD LineIndex,DWORD LineCnt)
{
DWORD ReadBytes;
if((m_ImageFormat==IMAGE_UNKNOWN)||(m_hImgFile==INVALID_HANDLE_VALUE))
return 0;
SetFilePointer(m_hImgFile,
m_FirstLineOffset+LineIndex*m_ImageLineBytes,
NULL,FILE_BEGIN);
ReadFile(m_hImgFile,pBuf,m_ImageLineBytes*LineCnt,&ReadBytes,NULL);
return ReadBytes;
}
DWORD CTifImage::OpenImage(char * pFileName)
{
WORD ItemCount;
DWORD i,temp,errorCode=0;
DWORD ResolutionUnit=2;
TIFHEADER TifHeader;
PIFDITEM pIFDItem;
if(m_hImgFile!=INVALID_HANDLE_VALUE)
CloseImage();
//initialize the default value
InitMemberVars();
m_ImageFormat=IMAGE_UNKNOWN;
m_SamplesPerPixel=1;
m_BitsPerSample=1;
m_Compress=1;
m_xRes=72;
m_yRes=72;
m_Predictor=1;
m_hImgFile=CreateFile(pFileName,GENERIC_READ,0,0,OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,0);
if(m_hImgFile==INVALID_HANDLE_VALUE)
{
errorCode=IDS_FILEOPENERROR;
goto ERROR_DISPATCH;
}
if((!ReadFile(m_hImgFile,&TifHeader,sizeof(TIFHEADER),&temp,0))
|| (temp!=sizeof(TIFHEADER)))
{
errorCode=IDS_READFILEERROR;
goto ERROR_DISPATCH;
}
if((TifHeader.ByteOrder!=0x4949)||(TifHeader.Version!=0x002a))
{
errorCode=IDS_FORMATERROR;
goto ERROR_DISPATCH;
}
SetFilePointer(m_hImgFile,TifHeader.IFDOffset,NULL,FILE_BEGIN);
if((!ReadFile(m_hImgFile,&ItemCount,sizeof(ItemCount),&temp,0))
|| temp!=sizeof(ItemCount))
{
errorCode=IDS_READFILEERROR;
goto ERROR_DISPATCH;
}
pIFDItem=(PIFDITEM)VirtualAlloc(NULL,ItemCount*(sizeof(IFDITEM)),
MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);
if(pIFDItem==NULL)
{
errorCode=IDS_MEMORY_INSUFFICIENT;
goto ERROR_DISPATCH;
}
if((!ReadFile(m_hImgFile,pIFDItem,ItemCount*(sizeof(IFDITEM)),&temp,0))
|| temp!=ItemCount*(sizeof(IFDITEM)))
{
VirtualFree(pIFDItem,0,MEM_RELEASE);
errorCode=IDS_READFILEERROR;
goto ERROR_DISPATCH;
}
for(i=0;i<=ItemCount;i++)
{
switch(pIFDItem[i].TifTag)
{
case tagImageWidth: //Length=1
if(pIFDItem[i].DataType==TIFFlong)
m_ImageWidth=pIFDItem[i].ulData;
else
m_ImageWidth=pIFDItem[i].ulData&0xffffL;
break;
case tagImageLength: //Length=1
if(pIFDItem[i].DataType==TIFFlong)
m_ImageDepth=pIFDItem[i].ulData;
else
m_ImageDepth=pIFDItem[i].ulData&0xffffL;
break;
case tagSamplesPerPixel: //Length=1
m_SamplesPerPixel=pIFDItem[i].ulData&0xffffL;
break;
case tagBitsPerSample: //Length>=1,=SamplesPerPixel
if(pIFDItem[i].DataLength>2)
{
WORD wData;
SetFilePointer(m_hImgFile,pIFDItem[i].ulData,NULL,FILE_BEGIN);
ReadFile(m_hImgFile,&wData,sizeof(WORD),&temp,0);
m_BitsPerSample=wData;
}
else
m_BitsPerSample=pIFDItem[i].ulData&0xffffL;
break;
case tagPhotometricInterp: //Length=1
m_PhotometricInterpretatio n=pIFDItem[i].ulData&0xffffL;
break;
case tagRowsPerStrip: //Length=1
if(pIFDItem[i].DataType==TIFFlong)
m_RowsPerStrip=pIFDItem[i].ulData;
else
m_RowsPerStrip=pIFDItem[i].ulData&0xffffL;
break;
case tagStripOffsets: //Length>=1
if(pIFDItem[i].DataLength>1)
{
if(pIFDItem[i].DataType==TIFFlong)
{
SetFilePointer(m_hImgFile,pIFDItem[i].ulData,NULL,FILE_BEGIN);
ReadFile(m_hImgFile,&m_FirstLineOffset,sizeof(DWORD),&temp,0);
}
else if(pIFDItem[i].DataLength>2)
{
WORD wData;
SetFilePointer(m_hImgFile,pIFDItem[i].ulData,NULL,FILE_BEGIN);
ReadFile(m_hImgFile,&wData,sizeof(WORD),&temp,0);
m_FirstLineOffset=(DWORD)wData;
}
else
{
m_FirstLineOffset=pIFDItem[i].ulData&0xffffL;
}
}
else if(pIFDItem[i].DataType==TIFFshort)
m_FirstLineOffset=pIFDItem[i].ulData&0xffffL;
else
m_FirstLineOffset=pIFDItem[i].ulData;
m_StripCount=pIFDItem[i].DataLength;
break;
case tagStripByteCounts:
if(pIFDItem[i].DataLength>1)
{
if(pIFDItem[i].DataType==TIFFlong)
{
SetFilePointer(m_hImgFile,pIFDItem[i].ulData,NULL,FILE_BEGIN);
ReadFile(m_hImgFile,&m_BytesPerStrip,sizeof(DWORD),&temp,0);
}
else if(pIFDItem[i].DataLength>2)
{
WORD wData;
SetFilePointer(m_hImgFile,pIFDItem[i].ulData,NULL,FILE_BEGIN);
ReadFile(m_hImgFile,&wData,sizeof(WORD),&temp,0);
m_BytesPerStrip=(DWORD)wData;
}
else
{
m_BytesPerStrip=pIFDItem[i].ulData&0xffffL;
}
}
else if(pIFDItem[i].DataType==TIFFshort)
m_BytesPerStrip=pIFDItem[i].ulData&0xffffL;
else
m_BytesPerStrip=pIFDItem[i].ulData;
break;
case tagCompression: //Length=1
m_Compress=pIFDItem[i].ulData&0xffffL;
break;
case tagXResolution: //Length=1
{
DWORD RData1=0,RData2=0;
SetFilePointer(m_hImgFile,pIFDItem[i].ulData,NULL,FILE_BEGIN);
ReadFile(m_hImgFile,&RData1,sizeof(RData1),&temp,NULL);
ReadFile(m_hImgFile,&RData2,sizeof(RData2),&temp,NULL);
if(RData2)
m_xRes=(DWORD)(RData1/RData2);
else
m_xRes=0;
}
break;
case tagYResolution: //Length=1
{
DWORD RData1=0,RData2=0;
SetFilePointer(m_hImgFile,pIFDItem[i].ulData,NULL,FILE_BEGIN);
ReadFile(m_hImgFile,&RData1,sizeof(RData1),&temp,NULL);
ReadFile(m_hImgFile,&RData2,sizeof(RData2),&temp,NULL);
if(RData2)
m_yRes=(WORD)(RData1/RData2);
else
m_yRes=0;
}
break;
case tagResolutionUnit: //Length=1
ResolutionUnit=pIFDItem[i].ulData&0x0FFFFL;
break;
case tagPredictor:
m_Predictor=pIFDItem[i].ulData&0xFFFFL;
break;
default:
break;
}
}
if(ResolutionUnit==UNIT_cm)
{
m_xRes=(DWORD)(m_xRes*2.54);
m_yRes=(DWORD)(m_yRes*2.54);
}
m_ImageLineBytes=(m_ImageWidth+7)/8;
VirtualFree(pIFDItem,0,MEM_RELEASE);
if(m_BitsPerSample==0)
temp=1;
else
temp=m_BitsPerSample;
if(m_SamplesPerPixel)
temp*=m_SamplesPerPixel;
m_Colors=1<<temp;
m_ImageFormat=IMAGE_TIF;
return 0;
ERROR_DISPATCH:
switch(errorCode)
{
case IDS_FILEOPENERROR:
break;
case IDS_MEMORY_INSUFFICIENT:
case IDS_READFILEERROR:
case IDS_FORMATERROR:
CloseHandle(m_hImgFile);
m_hImgFile=INVALID_HANDLE_VALUE;
break;
}
return errorCode;
}