C语言-编程实例-显示BMP图象的程式

2008-02-23 05:26:12来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

640*480 256 色 .BMP 文档显示程式,能够浏览、同时显示 4 幅图象,也能够 在屏幕上开一个窗口显示 .BMP 图象,并能够使用上下左右箭头键、PageUp/PageDown、Cl Left、Cl Right键浏览整幅图象,在S3、ATI等VGA卡上 调试通过

/*
SHOWBMP.C --- Show .BMP files images for SVGA 640*480(256/16) mode
M.L.Y 2000.9, 2000.12

Please compile this file by Borland C 3.1:
BCC -ml SHOWBMP.C
*/

#include <sio.h>
#include <slib.h>
#include <conio.h>
#include <dir.h>
#include "GCFSVGA.C"

typedef suct
{
int bfType; /* 文档类型, 必须为 "BM" (0x4D42) */
long bfSize; /* 文档的大小(字节) */
int bfReserved1; /* 保留, 必须为 0 */
int bfReserved2; /* 保留, 必须为 0 */
long bfoffBits; /* 位图阵列相对于文档头的偏移量(字节) */
} BITMAPFILEHEADER; /* 文档头结构 */

typedef suct
{
long biSize; /* size of BITMAPINFOHEADER */
long biWidth; /* 位图宽度(像素) */
long biHeight; /* 位图高度(像素) */
int biPlanes; /* 目标设备的位平面数, 必须置为1 */
int biBitCount; /* 每个像素的位数, 1,4,8或24 */
long biCompress; /* 位图阵列的压缩方法,0=不压缩 */
long biSizeImage; /* 图像大小(字节) */
long biXPelsPerMeter; /* 目标设备水平每米像素个数 */
long biYPelsPerMeter; /* 目标设备垂直每米像素个数 */
long biClrUsed; /* 位图实际使用的颜色表的颜色数 */
long biClrImportant; /* 重要颜色索引的个数 */
} BITMAPINFOHEADER; /* 位图信息头结构 */

typedef suct
{
USGC rgbBlue;
USGC rgbGreen;
USGC rgbRed;
USGC rgbReserved;
} RGBQUAD;

BITMAPFILEHEADER FileHead;
BITMAPINFOHEADER InfoHead;
int gl_index_color = NO; /* first .BMP file */

/* ------------------------------------------------------------------------- */
int read_palette(FILE *fp, USGC pal[][3], int colornum)
/*
将文档(指针fp)的当前位置的调色板数据读到 pal 中,colornum 是颜色数
*/
{
int i;

memset(pal, 0, 3*colornum);
for(i = 0; i < colornum; i )
{
pal[i][2] = (char)fgetc(fp) >> 2; /* Blue */
pal[i][1] = (char)fgetc(fp) >> 2; /* Green */
pal[i][0] = (char)fgetc(fp) >> 2; /* Red */
fgetc(fp);
}
return 0;
}

/* ------------------------------------------------------------------------- */
int show_bmp(FILE *fp, int color_index[256])
/*
按当前参数重新显示 .BMP 文档(文档指针 fp) (2色,16色或256色)
若是非第一幅图象,以第一幅图象调色板为准,颜色号索引表为 color_index
返回: 0 --- ok
-1 --- 显示图象时读文档出错
*/
{
int y, n, i, j, k;
long file_pos;
USGC buf[4096]; /* 文档中读出的一行图象 */
USGC linebuf[4096]; /* line buffer (一行图象) */

if(gl_browse_bmp == 1 && gn_x0 == gn_x0_old && gn_y0 == gn_y0_old)
return 0;
gn_x0_old = gn_x0;
gn_y0_old = gn_y0;

for(y = 0; y < gn_win_h; y )
{
memset(linebuf, 0, 640);

if(gn_x0 >= gn_pic_w || y gn_y0 >= gn_pic_h) n = 0;
else if(gn_x0 gn_win_w > gn_pic_w) n = gn_pic_w - gn_x0;
else n = gn_win_w;

/* 从文档头开始算: */
/*
file_pos = FileHead.bfoffBits
(long)(gn_pic_h - 1 - y - gn_y0) * gn_line_bytes gn_x0;
*/
file_pos = FileHead.bfoffBits
(long)(gn_pic_h - 1 - y - gn_y0) * gn_line_bytes;

/* 大部分书上是从文档尾开始算, 正向偏移: */
/* file_pos = FileHead.bfSize -
(long)(y gn_y0 1) * gn_line_bytes gn_x0; */

if(n > 0)
{
fseek(fp, file_pos, SEEK_SET);
/* 假如采用反向偏移: */
/* fseek(fp, -file_pos, SEEK_END); */
/*
if(fread(linebuf, 1, n, fp) != n)
return -1;
*/
if(fread(buf, 1, gn_line_bytes, fp) != gn_line_bytes)
return -1;
for(i = 0, j = 0; i < gn_line_bytes; i )
{
for(k = 0; k < gn_pix_pb; k )
{
linebuf[j ] = (buf[i] & gc_base) >> (8 - gn_bit_pp);
buf[i] <<= gn_bit_pp;
}
}

if(gl_index_color == YES)
{
for(i = 0; i < n; i )
linebuf[i] = color_index[linebuf[i>;
}
}
/*
VESA_putimage_256(y gn_win_top, gn_win_left, linebuf, gn_win_w,
IMG_COPY_PUT);
*/
if(gn_vid_color_num == 16)
VGA_putimage_16(y gn_win_top, gn_win_left, linebuf gn_x0, gn_win_w,
IMG_COPY_PUT);
else /* gn_vid_color_num = 256 */
VESA_putimage_256(y gn_win_top, gn_win_left, linebuf gn_x0, gn_win_w,
IMG_COPY_PUT);
/* 下列语句在 640*480*256 方式下因 buffer 超过 64K , 所以是错误的:
p



[1] [2] [3] 下一页

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇: C语言-编程实例-合并文档程式

下一篇: C语言-编程实例-文档加密一例

热门词条
热门标签