📄 imagefile.cpp
字号:
// ImageFile.cpp
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
//--------------------------------------------------------------
// BMP
BOOL CImage::LoadBMP(LPCSTR lpstrFileName)
{
BITMAPFILEHEADER BFH;
BITMAPINFOHEADER BIH;
RGBQUAD ColorTab[256];
FILE *fp;
fp=fopen(lpstrFileName,"rb");
if (fp==NULL)
return(FALSE);
fread(&BFH,sizeof(BITMAPFILEHEADER),1,fp);
fread(&BIH,sizeof(BITMAPINFOHEADER),1,fp);
if ((BFH.bfType!='MB')||(BIH.biCompression !=0)) {
fclose(fp);
return(FALSE);
}
Create(BIH.biWidth,BIH.biHeight,BIH.biBitCount,0);
if (nNumColors>0) {
fread(ColorTab,4,nNumColors,fp);
SetColorTable(0,nNumColors,ColorTab);
}
fseek(fp,BFH.bfOffBits,SEEK_SET);
fread(lpBits,nSize,1,fp);
fclose(fp);
return(TRUE);
}
BOOL CImage::SaveBMP(LPCSTR lpstrFileName)
{
BITMAPFILEHEADER BFH={'MB',0,0,0,0};
BITMAPINFOHEADER Bmih={40,1,1,1,8,0,0,0,0,0,0};
RGBQUAD ColorTab[256];
DWORD dwBmiSize;
FILE *fp;
dwBmiSize=40+4*nNumColors;
fp=fopen(lpstrFileName,"w+b");
if (fp==NULL)
return(FALSE);
BFH.bfSize =sizeof(BITMAPFILEHEADER)+dwBmiSize+nSize;
BFH.bfOffBits=sizeof(BITMAPFILEHEADER)+
sizeof(BITMAPINFOHEADER)+nNumColors*sizeof(RGBQUAD);
Bmih.biWidth = nWidth;
Bmih.biHeight = nHeight;
Bmih.biBitCount = nBitCount;
fwrite(&BFH,1,sizeof(BITMAPFILEHEADER),fp);
fwrite((BYTE*)&Bmih,1,40,fp);
if (nBitCount<=8) {
GetColorTable(0,nNumColors,ColorTab);
fwrite(ColorTab,4,nNumColors,fp);
}
fwrite(lpBits,1,nSize,fp);
fclose(fp);
return(TRUE);
}
// BMP
//--------------------------------------------------------------
// TIF
BOOL CImage::LoadTIF(LPCSTR lpstrFileName)
{
DWORD ColorMap;
FILE *fp;
struct TIF_IFH head;
struct TIF_DE dir[25];
WORD tif_pal[768];
WORD k,m,n,t,nn,c1,c2,Dx,Dy,Bits;
WORD TifBytesPerLine,OffBits,ImageType,Compression;
BYTE VgaPal[768],BmpPal[1024],*buf,*p;
int i,j,flag=0;
fp=fopen(lpstrFileName,"rb");
if (fp==NULL)
return(FALSE);
fread(&head,1,8,fp);
fseek(fp,head.FirstIFD,SEEK_SET);
fread(&nn,2,1,fp);
fread(dir,12,nn,fp);
for (i=0;i<nn;i++) {
switch(dir[i].Tag) {
case IMAGEWIDTH :
Dx=(WORD) dir[i].ValOff;
break;
case IMAGELENGTH :
Dy=(WORD) dir[i].ValOff;
break;
case BITSPERSAMPLE :
if (dir[i].Length>2) Bits=24;
else Bits=(WORD) dir[i].ValOff;
break;
case COMPRESSION :
Compression=(WORD) dir[i].ValOff;
break;
case PHOTOMETRICINTERP :
ImageType=(WORD) dir[i].ValOff;
break;
case STRIPOFFSETS :
if (dir[i].Length==1)
OffBits=(WORD) dir[i].ValOff;
else {
fseek(fp,dir[i].ValOff,SEEK_SET);
fread(&OffBits,4,1,fp);
}
break;
case COLORMAP :
ColorMap=dir[i].ValOff;
n=(WORD) dir[i].Length;
fseek(fp,ColorMap,SEEK_SET);
fread(tif_pal,2,n,fp);
p=(BYTE *) VgaPal;
n/=3;
for (m=0;m<n;m++) {
for (j=0,k=0;j<3;j++,k+=n)
p[3*m+j] = (tif_pal[m+k] >> 8) & 0xff;
}
break;
default :
break;
}
if (ImageType<2) {
p=(BYTE *) VgaPal;
if (Bits==1) {
if (ImageType==0) { c1=0; c2=255; }
else { c1=255; c2=0; }
for (j=0;j<3;j++) p[j] =(BYTE) c2;
for (j=0;j<3;j++) p[3+j]=(BYTE) c1;
}
else {
for (t=0;t<256;t++) {
k=t;
if (ImageType==0) k=255-k;
for (j=0;j<3;j++) p[3*t+j]=(BYTE) k;
}
}
}
}
if (Compression!=1) {
fclose(fp);
return(FALSE);
}
nWidth =Dx;
nHeight =Dy;
nBitCount=Bits;
Create(nWidth,nHeight,nBitCount,0);
if (nBitCount==1) TifBytesPerLine=(nWidth+7)/8;
else if (nBitCount==4) TifBytesPerLine=(nWidth+1)/2;
else if (nBitCount==8) TifBytesPerLine=nWidth;
else if (nBitCount==24) TifBytesPerLine=3*nWidth;
for (i=0;i<nNumColors;i++) {
for (j=0;j<3;j++) {
BmpPal[4*i+j]=VgaPal[3*i+2-j];
}
SetColorTable(0,nNumColors,(RGBQUAD*)BmpPal);
}
buf=lpBits+(nHeight-1)*nBytesPerLine;
fseek(fp,OffBits,SEEK_SET);
for (i=0;i<nHeight;i++) {
fread(buf,1,TifBytesPerLine,fp);
if (nBitCount==24) {
for (j=0,k=0;j<nWidth;j++,k+=3) {
m=buf[k+2];
buf[k+2]=buf[k];
buf[k]=(BYTE) m;
}
}
buf-=nBytesPerLine;
}
fclose(fp);
return(TRUE);
}
BOOL CImage::SaveTIF(LPCSTR lpstrFileName)
{
struct TIF_IFH head;
struct TIF_DE dir[]={
0x100,4,1,0, 0x101,4,1,0,
0x102,3,1,0, 0x103,3,1,1,
0x106,3,1,0, 0x111,4,1,0,
0x115,3,1,0, 0x140,3,0x300,0
};
RGBQUAD ColorTab[256];
long long2,ll;
WORD tif_pal[768];
int i,j,k,m,n,t,flag=0;
int OffBits,ImageType,TifBytesPerLine;
BYTE *buf,*buf1,*p;
FILE *fp;
fp=fopen(lpstrFileName,"w+b");
if (fp==NULL)
return(FALSE);
if (nBitCount<=8)
GetColorTable(0,nNumColors,ColorTab);
switch(nBitCount){
case 1:
if (ColorTab[0].rgbBlue==255)
ImageType=0;
else
ImageType=1;
TifBytesPerLine=(nWidth+7)/8;
break;
case 4:;
ImageType=3;
TifBytesPerLine=(nWidth+1)/2;
break;
case 8:
ImageType=3;;
TifBytesPerLine=nWidth;
break;
case 24:
ImageType=2;;
TifBytesPerLine=3*nWidth;
break;
}
memset(head.ByteOrder,'I',2);
head.Version = 0x2a;
head.FirstIFD = 8;
dir[0].ValOff = nWidth;
dir[1].ValOff = nHeight;
dir[4].ValOff = ImageType;
if (nBitCount==24) dir[6].ValOff = 3;
else dir[6].ValOff = 1;
n=7;
if (dir[4].ValOff==3) n++;
long2=10+12*n+4;
if (nBitCount==24) {
dir[2].Length = 3;
dir[2].ValOff = long2;
long2+=6;
}
else dir[2].ValOff = nBitCount;
OffBits=long2;
if (dir[4].ValOff==3) {
if (nBitCount==8)
OffBits+=768*2;
else if (nBitCount==4) {
OffBits+=48*2;
dir[7].Length=0x30;
}
dir[7].ValOff=long2;
}
dir[5].ValOff=OffBits;
ll=0;
fwrite(&head,8,1,fp);
fwrite(&n,2,1,fp);
fwrite(dir,12,n,fp);
fwrite(&ll,4,1,fp);
if (nBitCount==24) {
for (j=0,m=8;j<3;j++)
fwrite(&m,2,1,fp);
}
if (dir[4].ValOff==3) {
p=(BYTE *) ColorTab;
if (nBitCount==4) k=16;
else k=256;
for (i=0;i<3;i++) {
for (j=0;j<k;j++) {
n=((int) p[4*j+2-i]) & 0xff;
m=n | (n<<8);
tif_pal[k*i+j]=m;
}
}
if (nBitCount==8)
fwrite(tif_pal,2,768,fp);
else if (nBitCount==4)
fwrite(tif_pal,2,48,fp);
}
buf1=lpBits+(nHeight-1)*nBytesPerLine;
buf =(BYTE*) malloc(4*(nWidth+1));
fseek(fp,OffBits,SEEK_SET);
for (i=0;i<nHeight;i++) {
memcpy(buf,buf1,nBytesPerLine);
if (nBitCount==24) {
for (j=0,k=0;j<nWidth;j++,k+=3) {
t=buf[k];
buf[k]=buf[k+2];
buf[k+2]=(BYTE) t;
}
}
fwrite(buf,1,TifBytesPerLine,fp);
buf1-=nBytesPerLine;
}
fclose(fp);
free(buf);
return(TRUE);
}
// TIF
//--------------------------------------------------------------
// GIF
int index,rement;
char rem;
char *CTfirst,*CTlast,strbuf[256];
int *CTnext,*CTlink,CLEAR,EOI,len,max,next;
int LoadCode(int len,FILE *fp)
{
int value,mask,start,used;
start=value=0;
while(len > 0) {
if (rement == 0) {
while(index == 0) index=getc(fp);
index--;
rem=(unsigned char) getc(fp);
rement=8;
}
if (len > rement) used = rement;
else used = len;
rement -= used;
mask = (0xff>>(8-used));
mask &= rem; rem >>= used;
mask <<= start; start += used;
value |= mask; len -= used;
}
return(value);
}
void InitStringTable(int size,int flag)
{
int i;
len=size+1; max=1<<len;
CLEAR=1<<size; EOI=CLEAR+1;
next=CLEAR+2;
for (i=0;i<CLEAR;i++) {
CTfirst[i]=i; CTlast[i]=i;
if (flag==1) CTlink[i]=-1;
else {
CTlink[i]=-2; CTnext[i]=-1;
}
}
for (i=CLEAR;i<4096;i++) {
CTlink[i]=-2;
if (flag==2) CTnext[i]=-1;
}
}
void AddStringToTable(int S,int K)
{
CTlast[next] =CTfirst[K];
CTlink[next] =S;
CTfirst[next]=CTfirst[S];
if (++next == max) {
if (len < 12) {
len++; max<<=1;
}
}
}
int StringFromCode(int i,int K,BYTE *buff)
{
while(K != -1) {
buff[i++]=CTlast[K]; K=CTlink[K];
}
return(i);
}
int WriteString(int xx,int i,BYTE *buff,BYTE *buffer)
{
for (i--;i>=0;i--) buffer[xx++]=buff[i];
return(xx);
}
void unpack_LZWline(FILE *fp,int width,BYTE *buffer,int flag)
{
static int size,K,S,xx;
int i;
BYTE buff[1024];
if (flag > 0) {
CTfirst=(char*) malloc(4096);
CTlast =(char*) malloc(4096);
CTnext =(int *) malloc(4096*sizeof(int));
CTlink =(int *) malloc(4096*sizeof(int));
rement=0; rem=0;
index=0;
S=-1; xx=0;
fread(&size,1,1,fp);
InitStringTable(size,1);
}
else if (flag==0) {
if (xx >= width) {
if (xx>width)
for (i=0;i<xx-width;i++) buffer[i]=buffer[i+width];
xx-=width;
}
while((K=LoadCode(len,fp)) != EOI) {
if (K == CLEAR) {
InitStringTable(size,1);
S=-1;
}
else {
if (S != -1) {
if (CTlink[K] == -2)
AddStringToTable(S,S);
else AddStringToTable(S,K);
}
i =StringFromCode(0,K,buff);
xx=WriteString(xx,i,buff,buffer);
S=K;
if (xx >= width) break;
}
}
}
else {
free(CTfirst);
free(CTlast);
free(CTnext);
free(CTlink);
}
}
void WriteCode(int code,int len,FILE *fp)
{
int aln,used,cl;
cl=len; aln=rement+len;
while(aln >= 8) {
if (rement > 0) {
used=8-rement;
strbuf[index++]=rem|(code<<rement);
code=code >> used;
cl -= used; rement=0;
}
else {
strbuf[index++]=code;
cl -= 8; code=code >> 8;
}
aln-=8;
if (index == 256) {
strbuf[0]=(char) 0xff;
fwrite(strbuf,index,1,fp);
index=1;
}
}
if (rement == 0) {
rem=code; rement=cl;
}
else {
rem|=(code << rement); rement+=cl;
}
}
int IsInTable(int S,BYTE K)
{
int code;
if (S==-1) code=K;
else if (CTlink[S]==-2) {
CTlink[S]=next; CTlast[next++]=K;
code=-1;
}
else {
code=CTlink[S];
while((CTnext[code]!=-1) && (CTlast[code]!=K))
code=CTnext[code];
if (CTlast[code] != K) {
CTnext[code]=next; CTlast[next++]=K;
code=-1;
}
}
return(code);
}
void pack_LZWline(FILE *fp,int width,BYTE *buffer,int flag)
{
static int size,S;
BYTE K,*ptr;
int j,SK;
if (flag > 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -