武汉g2000专卖店:framebuffer画bmp

来源:百度文库 编辑:偶看新闻 时间:2024/04/29 00:14:54
/*
* $Id: ddlist.h,v1.0  2007/8/2 09:41:16 bolidhi Exp $
*
* heap.h: the private heap header.
*
* Copyright (C) 2006 ~ 2008 bolidehi .
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include "lib_type.h"
#include "read_bmp.h"


#define BI_RGB 0x00L
#define BI_RLE8 0x01L
#define BI_RLE4 0x02L
#define BI_BITFIELDS 0x03L


typedef unsigned char BYTE;
typedef signed char SBYTE;
typedef unsigned short WORD;
typedef signed short SWORD;
typedef unsigned short USHORT;
typedef signed   short SHORT;
typedef unsigned int DWORD;
typedef signed   int    SDWORD;
typedef unsigned int UINT;
typedef unsigned long ULONG;
typedef  signed  long SLONG;

/*bitmap file header structure*/
typedef struct _file_header file_header;
struct _file_header
{
BYTE type[2]; //bitmap file type;
DWORD size; //bitmap file size;
WORD reserved1;
WORD reserved2;
DWORD offset;
};
#define FILE_HEADER_SIZE 14

/*bitmap windows information head structure*/
typedef struct _info_head info_head;
struct _info_head
{
DWORD size;
DWORD width;
DWORD height;
WORD planes;
WORD bitcount;
DWORD compression;
DWORD sizeimage;
DWORD xpixelspermeter;
DWORD ypixelspermeter;
DWORD colorused;
DWORD colorimportant;
};
#define INFO_HEAD_SIZE 40

/*bitmap os2 information head structure*/
typedef struct _core_head core_head;
struct _core_head
{
DWORD size;
WORD width;
WORD height;
WORD planes;
WORD bitcount;
} ;
#define CORE_HEAD_SIZE 12

#define wswap(x) (x)
#define dwswap(x) (x)
#define dwread(addr)((((unsigned char *)(addr))[0] | \
(((unsigned char *)(addr))[1] << 8) | \
(((unsigned char *)(addr))[2] << 16) | \
(((unsigned char *)(addr))[3] << 24)))


#define _ROUND8(n) (((n) +7) /8)

/**
* read_image_buf: read image buffer to dest in specices size
* @img_buf : device image buffer;
* @dest :destion buffers
* @size : size of reader buffer;
* return the real readed size
*/
size_t read_image_buf(img_buffer *img_buf, void *dest, size_t size)
{
        size_t ret;

        if(eof_image_buf(img_buf))
                return 0;
        ret = img_buf->offset + size > img_buf->size ? img_buf->size - img_buf->offset : size;
        memcpy(dest, (char *)(img_buf->start)+img_buf->offset, size);
//DBG_INFO("dest=%s--buf=%s--start=%d--offset=%d--size=%d\n",(char *)dest, ((char *)(img_buf->start) + img_buf->offset), (char *)(img_buf->start), img_buf->offset, (size_t)size);
        img_buf->offset += size;

        return ret;
}
/**
* seek_image_buf: seek image buffer to dest in specices size
* @img_buf : device image buffer;
* @offset : seeked offset
* @whence : seeked postion
* return seeked postion
*/
int seek_image_buf(img_buffer *img_buf, size_t offset, int whence)
{
        int pos;
        switch(whence)
        {
        case SEEK_SET:
                if(offset >= img_buf->size || offset < 0)
                        return -1;
                img_buf->offset = offset;
                break;

        case SEEK_CUR:
                pos = img_buf->size + offset;
                if(pos >= img_buf->size || pos < 0)
                        return -1;
                img_buf->offset = pos;
                break;

        case SEEK_END:
                pos= img_buf->size + offset - 1;
                if (pos >= img_buf->size || pos < 0)
                        return -1L;
                img_buf->offset = pos;
                break;

        default:
                return - 1;
        }
        return img_buf->offset;
}

static void calc_pitch(int bpp, int width, int height, unsigned int *pitch)
{
int linesize=0;

switch(bpp)
{
case 1:
linesize = _ROUND8(width);
break;

case 2:
linesize = _ROUND8(width << 1);
break;
case 4:
linesize = _ROUND8(width << 2);
break;

case 8:
linesize = width;
break;

case 16:
linesize = width * 2;
break;

case 24:
linesize = width * 3;
break;

case 32:
linesize = width * 4;
break;
}
*pitch = (linesize + 3) & ~3;
DBG_INFO("linesize = %d--pitch=%d\n",linesize, *pitch);
}


static int decode_RLE8(BYTE *buf, img_buffer *img_buf)
{
int c, n;
BYTE *p = buf;

for( ;;)
{
switch( n = getc_image_buf(img_buf))
{
case EOF:
return 0;

case 0: /* 0 = escape*/
switch( n = getc_image_buf(img_buf))
{
case 0: /* 0 0 = end of current scan line*/
case 1: /* 0 1 = end of data*/
return 1;
case 2: /* 0 2 xx yy delta mode NOT SUPPORTED*/
getc_image_buf(img_buf);
getc_image_buf(img_buf);
continue;
default: /* 0 3..255 xx nn uncompressed data*/
for( c=0; c*p++ = getc_image_buf(img_buf);
if( n & 1)
getc_image_buf(img_buf);
continue;
}

  default:
c = getc_image_buf(img_buf);
while( n--) *p++ = c;
continue;
  }
}
}


static BYTE *p;
static int once;

static __inline void put4(int b)
{
static int last;
last = (last << 4) | b;
if(++once ==2)
{
*p ++ = last;
once = 0;
}
}


static int decode_RLE4(BYTE *buf, img_buffer *img_buf)
{
int c, n, c1, c2;
p = buf;
once = 0;
c1 = 0;

for (;;)
{
switch (n = getc_image_buf(img_buf))
{
case EOF:
return 0;

case 0: /* 0 = escape */
switch (n = getc_image_buf(img_buf))
{
case 0: /* 0 0 = end of current scan line */
case 1: /* 0 1 = end of data */
if (once)
put4(0);
return 1;

case 2: /* 0 2 xx yy delta mode NOT SUPPORTED */
getc_image_buf(img_buf);
getc_image_buf(img_buf);
continue;
default: /* 0 3..255 xx nn uncompressed data */
c2 = (n + 3) & ~3;
for (c = 0; c < c2; c++)
{
if ((c & 1) == 0)
c1 = getc_image_buf(img_buf);
if (c < n)
put4((c1 >> 4) & 0x0f);
c1 <<= 4;
}
continue;
}

default:
c = getc_image_buf(img_buf);
c1 = (c >> 4) & 0x0f;
c2 = c & 0x0f;
for (c = 0; c < n; c++)
put4((c & 1) ? c2 : c1);
continue;
}
}
}

int read_bmp(IMAGEHEADER *image, void *buffer, size_t size)
{
int h, compression =0 ;
int headsize;
file_header fheader;
info_head ihead;
core_head chead;
img_buffer img_buf;
BYTE head_buf[INFO_HEAD_SIZE];
BYTE *data = NULL;

init_image_buf(&img_buf, buffer, size);
if(read_image_buf(&img_buf, &head_buf, FILE_HEADER_SIZE) != FILE_HEADER_SIZE)
{
image->type = 0;
return 1;
}

fheader.type[0] = head_buf[0];
fheader.type[1] = head_buf[1];

if(*((WORD *)(&fheader.type)) != wswap(0x4D42)) //0x4D42='BM'
{
image->type = 0;
DBG_INFO(" This is not bitmap image\n");
return 1;
}

fheader.offset  = dwswap(dwread(&head_buf[10]));

if(read_image_buf(&img_buf, &headsize, sizeof(int)) != sizeof(int))
{
image->type =0;
return 1;
}

headsize = dwswap(headsize);

if(headsize == CORE_HEAD_SIZE)
{ /* read os/2 header */
if(read_image_buf(&img_buf,&head_buf, CORE_HEAD_SIZE - sizeof(DWORD)) !=
CORE_HEAD_SIZE - sizeof(DWORD))
{
return 1;
}
chead.width = wswap(*((WORD *)&head_buf[0]));
chead.height = wswap(*((WORD *)&head_buf[2]));
chead.planes = wswap(*((WORD *)&head_buf[4]));
chead.bitcount = wswap(*((WORD *)&head_buf[6]));

image->width = (int)chead.width;
image->depth = (int)chead.height;
image->bpp = chead.bitcount;
compression = BI_RGB;
}
else
{ /* read windows header */
if(read_image_buf(&img_buf,&head_buf, INFO_HEAD_SIZE - sizeof(DWORD)) !=
INFO_HEAD_SIZE - sizeof(DWORD))
{
return 1;
}

ihead.width = dwswap(*((DWORD*)&head_buf[0]));
ihead.height = dwswap(*((DWORD*)&head_buf[4]));
ihead.planes = dwswap(*((DWORD*)&head_buf[8]));
ihead.bitcount = dwswap(*((DWORD*)&head_buf[10]));
ihead.compression= dwswap(*((DWORD*)&head_buf[12]));
ihead.sizeimage = dwswap(*((DWORD*)&head_buf[16]));
ihead.xpixelspermeter = dwswap(*((DWORD*)&head_buf[20]));
ihead.ypixelspermeter = dwswap(*((DWORD*)&head_buf[24]));
ihead.colorused = dwswap(*((DWORD*)&head_buf[28]));
ihead.colorimportant = dwswap(*((DWORD*)&head_buf[32]));

image->width = (int)ihead.width;
image->depth = (int)ihead.height;
image->bpp = ihead.bitcount;
//image->pal_size =(int)ihead.colorused;
compression = ihead.compression;
}
if(image->bpp > 8 && image->bpp!=24)
{
    DBG_INFO("load_bmp: image bpp is not 1 4 8 or 24\n");
    return 1;
}

/*compreession = IMG_BGR;
image->planes = 1;*/
//image->type = IMAGE_TYPE_BMP;
calc_pitch(image->bpp, image->width, image->depth, &image->bytewidth);
/* Allocate image */
image->data =(BYTE*) malloc(image->bytewidth * image->depth);
if(image->data == NULL)
{
DBG_INFO(" Allocate image data failed\n");
goto err;
}
#if 0
if(image->bpp <= 8)
{
image->pal_tabs =(palette *)malloc(image->pal_size * sizeof(palette));
if(!image->pal_tabs) goto err;
/* get colormap*/
for(i =0; ipal_size;i++)
{
image->pal_tabs[i].b = getc_image_buf(&img_buf);
image->pal_tabs[i].g = getc_image_buf(&img_buf);
image->pal_tabs[i].r = getc_image_buf(&img_buf);
if(headsize !=CORE_HEAD_SIZE) getc_image_buf(&img_buf);
}
}
#endif

/* decode image data*/
seek_image_buf(&img_buf, fheader.offset, SEEK_SET);
h = image->depth;
//data = image->data + (h-1)* image->bytewidth ;
data = image->data;
switch(compression)
{
case BI_RLE8:
while(--h>=0)
{

if(!decode_RLE8(data, &img_buf))
break;
//data -= image->bytewidth ;
data += image->bytewidth ;
}
break;

case BI_RLE4:
while(--h>=0)
{
if(!decode_RLE4(data, &img_buf))
break;
//data -= image->bytewidth ;
data += image->bytewidth ;
}
break;

default:
while(--h>=0)
{
//DBG_INFO("---width=%d---\n",image->bytewidth);
if(read_image_buf(&img_buf, data, image->bytewidth) != image->bytewidth)
goto err;
//data -= image->bytewidth ;
data += image->bytewidth ;
}
break;
}
return 0;

err:
DBG_INFO("loadbmp:load image error\n");
if(image->data)
{
free(image->data);
}
/*
if(image->pal_tabs)
{
free(image->pal_tabs);
image->pal_size = 0;
}*/

return 1;
}

int cetc_renderbmp(IMAGEHEADER *p_img, const char *filename)
{
int fd;
struct stat st;
void *buff;
int ret;
DBG_INFO( "Enter \n");

if(filename !=NULL && *filename !='\0')
{
fd = open(filename, O_RDONLY, 0);
if(fd == -1)
{
DBG_INFO(" Open file %s failed\n", filename);
return 1;
}

if(0 != fstat(fd, &st))
{
DBG_INFO(" Get fd %d stat information failed\n", fd);
return 1;
}
buff = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if((int)buff == -1)
{
DBG_INFO(" mmap the fd %d failed\n", fd);
return 1;
}
ret = read_bmp(p_img, buff, st.st_size);
// DBG_INFO("p_img->data=%s\n",p_img->data);
munmap(buff, st.st_size);
close(fd);
return ret;
}
DBG_INFO(" Leave\n");
return 1;
}