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

📄 winbmp.c

📁 MinGUI 可视化程序代码
💻 C
字号:
 /******************************************************************************** Copyright  2006 National ASIC Center, All right Reserved** FILE NAME:      winbmp.c* PROGRAMMER:     ming.c* Date of Creation:   2006/08/8** DESCRIPTION:** NOTE:** FUNCTIONS LIST:* -----------------------------------------------------------------------------** -----------------------------------------------------------------------------** MODIFICATION HISTORY*     LastModify  2006/10/30******************************************************************************/#include "mingui.h"//---------------------------------------------------------------------------
extern int  CM_DecodeBMP(TImageHead *imgHead, STREAM *stream);
extern int  CM_DecodeLCDIMG(TImageHead *imgHead, const BYTE *pImage);
static int  CM_DecodeRLE4(BYTE *buf, STREAM *stream);
static int  CM_DecodeRLE8(BYTE *buf,STREAM *stream);
//---------------------------------------------------------------------------
int CM_DecodeBMP(TImageHead *imgHead, STREAM *stream)
{ int size,i,imgPitch,PalBlockSize;
  BYTE *imgBits;
  BMPFILEHEADER fileheader;
  BMPINFOHEADER infoheader;
  RGBQUAD tempPal[256];
  
  size=StreamRead(&fileheader,sizeof(WORD),stream);
  if(fileheader.bfType!=0x4d42 || size!=sizeof(WORD))  return false;

  size=StreamRead(&fileheader.bfSize,12,stream);
  if(size!=12)  return false;

  size=StreamRead(&infoheader,sizeof(DWORD),stream);
  if(size<sizeof(DWORD))  return false;
  
  if(infoheader.BiSize>=sizeof(BMPINFOHEADER))
  { size=StreamRead((BYTE *)&infoheader+4,sizeof(BMPINFOHEADER)-4,stream);
    if(size!=sizeof(BMPINFOHEADER)-4) return false;
   
    i=infoheader.BiSize - sizeof(BMPINFOHEADER);
    if(!i) StreamSeek(stream,i,SEEK_CUR);

    PalBlockSize = (fileheader.bfOffBits - sizeof(BMPINFOHEADER) - 14);
    imgHead->palsize=PalBlockSize>>2;
    imgHead->width=infoheader.BiWidth;
    imgHead->height=infoheader.BiHeight;
    imgHead->bpp=infoheader.BiBitCount; 
    imgHead->compression=infoheader.BiCompression;

    if(imgHead->palsize>0 && imgHead->palsize<=256)
    {       
      imgHead->transPal=(PIXEL *)GetMem(imgHead->palsize * sizeof(PIXEL));
      if(!imgHead->transPal)  return false;
      
      size=StreamRead(tempPal,PalBlockSize,stream);
      if(PalBlockSize!=size)  return false;
      if(imgHead->bpp<=8)
      { for(i=0;i<imgHead->palsize;i++)
        { imgHead->transPal[i]=ColorMapToPixel(&tempPal[i]);
        }
      }
    }
  }
  else if(infoheader.BiSize==sizeof(BMPCOREHEADER))
  { BMPCOREHEADER coreheader;
    size=StreamRead((BYTE *)&coreheader+4,sizeof(BMPCOREHEADER)-4,stream);
    if(size!=sizeof(BMPCOREHEADER)-4)  return false;
    imgHead->width=coreheader.bcWidth;
    imgHead->height=coreheader.bcHeight;
    imgHead->bpp=coreheader.bcBitCount;
    imgHead->compression=0;
 
    PalBlockSize = (fileheader.bfOffBits - 26);
    imgHead->palsize = PalBlockSize / 3;
    if(imgHead->palsize>0 && imgHead->palsize<=256)
    { BYTE *myPal=(BYTE *)tempPal;
      RGBQUAD rgbColor;
      imgHead->transPal=(PIXEL *)GetMem(imgHead->palsize * sizeof(PIXEL));
      if(!imgHead->transPal)  return false;
      size=StreamRead(myPal,PalBlockSize,stream);
      if(PalBlockSize!=size)  return false;
      rgbColor.a=0;
      for(i=0;i<imgHead->palsize;i++)
      { rgbColor.b=*myPal++;
        rgbColor.g=*myPal++; 
        rgbColor.r=*myPal++;
        imgHead->transPal[i]=ColorMapToPixel(&rgbColor);
      }
    }
  }
  else
  {  return false;
  }
 
  imgHead->pitch = ( (imgHead->width*imgHead->bpp+31)>>3 ) & ~0x3;
  if(imgHead->bpp==16)
  { if(imgHead->compression==BI_BITFIELDS)
    { if(*(DWORD *)&tempPal[1] == 0x03e0)
        imgHead->bpp=15;
    }
    else imgHead->bpp=15;
  }

  imgHead->bits = (BYTE *)GetMem(imgHead->pitch * imgHead->height);
  if(!imgHead->bits) return false;
  imgHead->bitsFromHeap=true;
 
  //fseek(f,fileheader.bfOffBits,0);

  i=imgHead->height;
  imgPitch=imgHead->pitch;
  imgBits=imgHead->bits + i*imgHead->pitch;
  if(imgHead->compression==BI_RLE8)
  { while (--i >= 0) 
    { imgBits-=imgPitch;
      if(!CM_DecodeRLE8(imgBits, stream))  return false;
	}
  }
  else if(imgHead->compression==BI_RLE4)
  { while (--i >= 0) 
    { imgBits-=imgPitch;
      if(!CM_DecodeRLE4(imgBits, stream))  return false;
	}
  }
  else
  { while (--i >= 0) 
    { imgBits-=imgPitch;
      StreamRead(imgBits,imgPitch,stream);
	}
  }

 
 
 return true;
}
//---------------------------------------------------------------------------
int CM_DecodeRLE8(BYTE *buf,STREAM *stream)
{ int c, n;
  BYTE *	p = buf;
  while(1)
  {	n = StreamGetByte(stream);
    switch(n) 
    { case EOF:  return(0);
	  case 0:    /* 0 = escape*/
             n = StreamGetByte(stream);	
			 switch(n) 
             { case 0: return(1);  /* 0 0 = end of current scan line*/
			   case 1: return(1);  /* 0 1 = end of data*/
			   case 2:  		   /* 0 2 xx yy delta mode - NOT SUPPORTED*/
				       (void)StreamGetByte(stream);
				       (void)StreamGetByte(stream);
				       continue;
			   default:			   /* 0 3..255 xx nn uncompressed data*/
				        for(c=0; c<n; c++)
				        	*p++ = StreamGetByte(stream);
				        if(n & 1)
					      (void)StreamGetByte(stream);
				        continue;
			}
	   default:
			  c = StreamGetByte(stream);
			  while(n--)
				*p++ = c;
			  continue;
	}
  }
}
//---------------------------------------------------------------------------
/*
 * Decode one line of RLE4, return 0 when done with all bitmap data
 */
int CM_DecodeRLE4(BYTE *buf, STREAM *stream)
{ static int	last;
  #define rle_put4(b)\
  { last = (last << 4) | (b);\
    if(++once == 2)\
    { *p++ = last;\
	  once = 0;\
    }\
  }  
  BYTE *p=buf;
  int	once=0,c, n, c1, c2;
  
  while(1) 
  { n = StreamGetByte(stream);
	switch(n) 
    { case EOF: return(0);
	  case 0:					/* 0 = escape*/
		     n =StreamGetByte(stream);
             switch(n) 
             { case 0: 			/* 0 0 = end of current scan line*/
				      if(once) 
                        rle_put4(0);
				      return(1);
			   case 1:				/* 0 1 = end of data*/
				      if(once)
					    rle_put4(0);
				      return(1);
			   case 2:				/* 0 2 xx yy delta mode - NOT SUPPORTED*/
			     	  (void)StreamGetByte(stream);
				      (void)StreamGetByte(stream);
				      continue;
			   default:			/* 0 3..255 xx nn uncompressed data*/
				       c2 = (n+3) & ~3;
				       for(c=0; c<c2; c++)
                       { if((c & 1) == 0)
							c1 = StreamGetByte(stream);
					     if(c < n)
							rle_put4((c1 >> 4) & 0x0f);
					     c1 <<= 4;
                       }
				       continue;
			}
	  default:
			c = StreamGetByte(stream);
			c1 = (c >> 4) & 0x0f;
			c2 = c & 0x0f;
			for(c=0; c<n; c++)
            {  rle_put4((c&1)? c2: c1);
            }
			continue;
		}
	}
}
//---------------------------------------------------------------------------
int  CM_DecodeLCDIMG(TImageHead *imgHead, const BYTE *pImage)
{   TLcdImageHead *LcdIMG=(TLcdImageHead *)pImage;
    int LcdScanMode;

    LcdScanMode=LcdIMG->scan;
    if(LcdScanMode&0x3)
    { DebugAlert("图像格式错误\n非水平方式扫描的位图!");
      return false;
    }

    imgHead->bpp=LcdIMG->bpp;
 
    if(LcdScanMode & 0x10)
    { imgHead->width=(LcdIMG->width[0]<<8)+LcdIMG->width[1];
      imgHead->height=(LcdIMG->height[0]<<8)+LcdIMG->height[1];
    }
    else
    { imgHead->width=LcdIMG->width[0] + (LcdIMG->width[1]<<8);
      imgHead->height=LcdIMG->height[0] + (LcdIMG->height[1]<<8);
    }
    
    if(imgHead->width<=0 || imgHead->height<=0)
    { return false;
    }

    imgHead->pitch = (imgHead->width*imgHead->bpp+7)/8;
    pImage+=sizeof(TLcdImageHead);    
    switch(imgHead->bpp)
    {  case 1:
       case 2:
       case 4: //LCD灰度图象
               { int i,j,palSize= 1<<imgHead->bpp;
                 DWORD rgbColor;
                 PIXEL *imgTransPal=(PIXEL *)GetMem(sizeof(PIXEL)*palSize);
                 if(!imgTransPal)return false;
                 else imgHead->transPal=imgTransPal;
                 imgHead->palsize=palSize;
                 j=imgHead->bpp<<1;
                 for(i=1;i<=palSize;i++)
                 { rgbColor= ( i * i * 255 ) >> j;
                   rgbColor=rgbColor|(rgbColor<<8)|(rgbColor<<16);
                   imgTransPal[palSize-i]=ColorMapToPixel((RGBQUAD *)&rgbColor);
                 }
               }
               break;
       case 8: /* 256 color */
               { int i,palSize;
                 PIXEL *imgTransPal;
                 RGBQUAD rgbColor;

                 if(LcdScanMode & 0x10)
                 {  palSize=*pImage++<<8;
                    palSize=palSize|*pImage++;
                 }
                 else
                 { palSize=*pImage++;
                   palSize=palSize|(*pImage++<<8);
                 }
                 if(palSize>0 && palSize<=256)
                 { imgHead->palsize=palSize;
                   imgTransPal=(PIXEL *)GetMem(sizeof(PIXEL)*palSize);
                   if(!imgTransPal)return false;
                   else imgHead->transPal=imgTransPal;
                 } else return false;
                 rgbColor.a=0;
                 for(i=0;i<palSize;i++)
                 { rgbColor.r = *pImage++;
                   rgbColor.g = *pImage++;
                   rgbColor.b = *pImage++;
                   imgTransPal[i]=ColorMapToPixel(&rgbColor);
                 }
               }
             break;
       case 16: { int is565=*pImage;
                  pImage+=2; 
                  if(is565==0) imgHead->bpp=15;
                  else if(is565!=1) return false;
                }
                break;
       case 24:
       case 32: pImage+=2;break;
       default: return false; 
    }

    imgHead->bits=(BYTE *)pImage;
    imgHead->bitsFromHeap=false;

    return true;
}
/*---------------------------------------------------------------------------END --- Thank you!                                                  ming.c---------------------------------------------------------------------------*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -