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

📄 bmp.c

📁 嵌入式下基于MiniGUI的Web Browser
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *File:     bmp.c *Author:   Zhu Zhiqiang *Company: * */#include <mgdconfig.h>#ifdef ENABLE_BMP#include <stdio.h>#include <glib.h>#include <minigui/common.h>#include <minigui/gdi.h>#include "image.h"#include "web.h"#include "cache.h"#include "dicache.h"#define DEBUG_LEVEL 6#include "debug.h"typedef enum {   DILLO_BMP_INIT,   DILLO_BMP_STARTING,   DILLO_BMP_READING,   DILLO_BMP_DONE,   DILLO_BMP_ERROR} DilloBmpState;typedef struct BITMAPFILEHEADER{   unsigned short bfType;   unsigned long  bfSize;   unsigned short bfReserved1;   unsigned short bfReserved2;   unsigned long  bfOffBits;} BITMAPFILEHEADER;typedef struct BITMAPINFOHEADER{   unsigned long  biSize;   unsigned long  biWidth;   unsigned long  biHeight;   unsigned short biBitCount;   unsigned long  biCompression;} BITMAPINFOHEADER;typedef struct WINBMPINFOHEADER  /* size: 40 */{   unsigned long  biSize;   unsigned long  biWidth;   unsigned long  biHeight;   unsigned short biPlanes;   unsigned short biBitCount;   unsigned long  biCompression;   unsigned long  biSizeImage;   unsigned long  biXPelsPerMeter;   unsigned long  biYPelsPerMeter;   unsigned long  biClrUsed;   unsigned long  biClrImportant;} WINBMPINFOHEADER;#define BI_RGB          0#define BI_RLE8         1#define BI_RLE4         2#define BI_BITFIELDS    3#define OS2INFOHEADERSIZE  12#define WININFOHEADERSIZE  40#define ReadGuchar(Buf)  *((guchar *)Buf)#define ReadShortInt(Buf) *((guchar *)Buf)|*((guchar *)Buf+1)<<8#define ReadInt(Buf) *((guchar *)Buf)|*((guchar *)Buf+1)<<8|*((guchar *)Buf+2)<<16|*((guchar *)Buf+3)<<24#define PIX2BYTES(n)    (((n)+7)/8)#define red 0#define green 2typedef struct _DilloBmp {   DilloImage *Image;   DilloUrl *url;   gint version;   BITMAPFILEHEADER fileheader;   BITMAPINFOHEADER infoheader;   guchar flag;   gint pitch;   gint effect_depth;   gint size;   gint line;//used by BI_RLE8   guint linerec;//how many line have received!   guint lineout;//how many line have written to dicache!   char *Data;   gint  bytessaved;//how many image data have be saved!   gint  bytesdelt;//how many image data have be delt!   size_t Start_Ofs, Skip, NewStart;   DilloBmpState state;   guint rmask, gmask, bmask;} DilloBmp;/* * Forward declarations */static DilloBmp *Bmp_new(DilloImage *Image, DilloUrl *url, gint version);static void Bmp_callback(int Op, CacheClient_t *Client);static void Bmp_write(DilloBmp *bmp, void *Buf, guint BufSize);static void Bmp_close(DilloBmp *bmp, CacheClient_t *Client);static int read_bmfileheader(guchar *f, BITMAPFILEHEADER *fileheader);static int read_win_bminfoheader(guchar *f, BITMAPINFOHEADER *infoheader);static int bmpComputePitch (int bpp, Uint32 width, Uint32* pitch, BOOL does_round);static void image_4bit_save (DilloBmp *bmp,guchar *f, guint Bufsize);static void image_8bit_save (DilloBmp *bmp,guchar *f, guint Bufsize);static void image_16bit_save(DilloBmp *bmp,guchar *f, guint Bufsize);static void image_24bit_save(DilloBmp *bmp,guchar *f, guint Bufsize);/* exported function */DwWidget *a_Bmp_image(const char *Type, void *P, CA_Callback_t *Call,                       void **Data){   DilloWeb *web = P;   DICacheEntry *DicEntry;   if ( !web->Image )      web->Image = a_Image_new(0, 0, NULL, 0);   /* Add an extra reference to the Image (for dicache usage) */   a_Image_ref(web->Image);   DicEntry = a_Dicache_get_entry(web->url);   if ( !DicEntry ) {      /* Let's create an entry for this image... */      DicEntry = a_Dicache_add_entry(web->url);      /* ... and let the decoder feed it! */      *Data = Bmp_new(web->Image, DicEntry->url, DicEntry->version);      *Call = (CA_Callback_t) Bmp_callback;   } else {      /* Let's feed our client from the dicache */      a_Dicache_ref(DicEntry->url, DicEntry->version);      *Data = web->Image;      *Call = (CA_Callback_t) a_Dicache_callback;   }   return DW_WIDGET (web->Image->dw);}/* * Finish the decoding process */static void Bmp_close(DilloBmp *bmp, CacheClient_t *Client){   a_Dicache_close(bmp->url, bmp->version, Client);   if(!bmp->Data)        g_free(bmp->Data);   g_free(bmp);}static DilloBmp *Bmp_new(DilloImage *Image, DilloUrl *url, gint version){   DilloBmp *bmp = g_malloc(sizeof(*bmp));   bmp->Image = Image;   bmp->url = url;   bmp->version = version;   bmp->state = DILLO_BMP_INIT;   bmp->Start_Ofs = 0;   bmp->bytessaved=0;   bmp->bytesdelt=0;   bmp->linerec=0;   bmp->lineout=0;   return bmp;}static void Bmp_callback (int Op, CacheClient_t *Client){   DEBUG_MSG (5, "Bmp_callback is called\n");   if (Op)      Bmp_close(Client->CbData, Client);   else      Bmp_write(Client->CbData, Client->Buf, Client->BufSize);}static void Bmp_write(DilloBmp *bmp, void *Buf, guint Bufsize){   DilloImgType type;   gint i;   unsigned long biSize;  gint ncol;   /*Save the received data to bmp->data*/    bmp-> rmask = 0x001f, bmp->gmask = 0x03e0, bmp->bmask = 0x7c00;    if (bmp->state == DILLO_BMP_INIT)    {       if(Bufsize>54)/*Make sure the header of the bmp is got!*/        {            if (read_bmfileheader (Buf, &bmp->fileheader) != 0)            {                bmp->state=DILLO_BMP_ERROR;                    return;            }            biSize =*((guchar *)Buf+14)|*((guchar *)Buf+15)<<8 ;            ncol = (bmp->fileheader.bfOffBits - biSize - 14) / 4;            if (biSize >= WININFOHEADERSIZE)            {       	        if (read_win_bminfoheader (Buf+14, &bmp->infoheader) != 0)                {                    bmp->state=DILLO_BMP_ERROR;                    return;                }            }            else if (biSize == OS2INFOHEADERSIZE)             {                bmp->state=DILLO_BMP_ERROR;                return;            }            else            {                 bmp->state=DILLO_BMP_ERROR;                 return;            }            bmp->effect_depth = bmp->infoheader.biBitCount;            bmpComputePitch (bmp->effect_depth, bmp->infoheader.biWidth,                                 (gint *)(&bmp->pitch), TRUE);           // biSize =bmp->pitch*bmp->infoheader.biHeight;            biSize =bmp->infoheader.biWidth*3*bmp->infoheader.biHeight;            if( !(bmp->Data =g_malloc(biSize)) )             {                 bmp->state=DILLO_BMP_ERROR;                 return;             }	   // bmp->Image->widget.RGBorBGR=0xaa;           if (bmp->infoheader.biBitCount == 1)            type = DILLO_IMG_TYPE_GRAY;           else             type = DILLO_IMG_TYPE_RGB;            a_Dicache_set_parms(bmp->url, bmp->version, bmp->Image,                             (guint)bmp->infoheader.biWidth,                             (guint)bmp->infoheader.biHeight,                             type);            bmp->state = DILLO_BMP_READING;        }    }  if (bmp->state == DILLO_BMP_READING)   {           switch (bmp->infoheader.biCompression)          {            case BI_BITFIELDS: /* ignore the bit fileds */                 bmp->rmask = ReadShortInt(Buf+14+bmp->infoheader.biSize);                 bmp->gmask = ReadShortInt(Buf+16+bmp->infoheader.biSize);                 bmp->bmask =ReadShortInt(Buf+18+bmp->infoheader.biSize);            case BI_RGB:                 if (bmp->infoheader.biBitCount == 4)                 {                   printf("start to process 4 bits image\n");                    image_4bit_save(bmp,Buf,Bufsize);                 }                 else if (bmp->infoheader.biBitCount == 8)                 {                   printf("start to process 8 bits image\n");                    image_8bit_save(bmp,Buf,Bufsize);                 }                 else if (bmp->infoheader.biBitCount == 16)                 {                   printf("start to process 16 bits image\n");                    image_16bit_save(bmp,Buf,Bufsize);                 }                 else if (bmp->infoheader.biBitCount == 24)                 {                   printf("start to process 24 bits image\n");                   image_24bit_save(bmp,Buf,Bufsize);                 }                else                {                    bmp->state=DILLO_BMP_ERROR;                    return;                }                 break;            default:                 bmp->state=DILLO_BMP_ERROR;                 return;        }             for(i=bmp->lineout;i<bmp->linerec;i++)       {          a_Dicache_write (bmp->Image, bmp->url, bmp->version,                         bmp->Data+i*bmp->infoheader.biWidth*3, 0,                         bmp->infoheader.biHeight-1-i);          bmp->lineout++;       }       if(bmp->lineout==bmp->infoheader.biHeight)       {          bmp->state = DILLO_BMP_DONE;       }   }}static int bmpComputePitch (int bpp, Uint32 width, Uint32* pitch, BOOL does_round){    Uint32 linesize;    int bytespp = 1;    if(bpp == 1)        linesize = PIX2BYTES (width);    else if(bpp <= 4)        linesize = PIX2BYTES (width << 2);    else if (bpp <= 8)        linesize = width;    else if(bpp <= 16) {        linesize = width * 2;        bytespp = 2;    } else if(bpp <= 24) {        linesize = width * 3;        bytespp = 3;    } else {        linesize = width * 4;        bytespp = 4;    }     /* rows are DWORD right aligned*/    if (does_round)        *pitch = (linesize + 3) & -4;    else        *pitch = linesize;    return bytespp;}static int read_win_bminfoheader(guchar *f, BITMAPINFOHEADER *infoheader){   WINBMPINFOHEADER win_infoheader;   win_infoheader.biWidth = ReadInt(f);   win_infoheader.biWidth = ReadInt(f+4);   win_infoheader.biHeight = ReadInt(f+8);   win_infoheader.biPlanes = ReadShortInt(f+12);   win_infoheader.biBitCount =ReadShortInt(f+14) ;   win_infoheader.biCompression =ReadInt(f+16) ;   win_infoheader.biSizeImage = ReadInt(f+20);   win_infoheader.biXPelsPerMeter = ReadInt(f+24);   win_infoheader.biYPelsPerMeter = ReadInt(f+28);   win_infoheader.biClrUsed = ReadInt(f+32);   win_infoheader.biClrImportant =ReadInt(f+36) ;   infoheader->biWidth = win_infoheader.biWidth;   infoheader->biHeight = win_infoheader.biHeight;   infoheader->biBitCount = win_infoheader.biBitCount;   infoheader->biCompression = win_infoheader.biCompression;   return 0;}static int read_bmfileheader(guchar *f, BITMAPFILEHEADER *fileheader){   fileheader->bfType =ReadShortInt(f) ;

⌨️ 快捷键说明

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