Files
30dayMakeOS/30_day/gview/gview.c
2016-05-20 14:05:13 +08:00

122 lines
2.9 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "apilib.h"
struct DLL_STRPICENV { /* 64KB */
int work[64 * 1024 / 4];
};
struct RGB {
unsigned char b, g, r, t;
};
/* bmp.nasm */
int info_BMP(struct DLL_STRPICENV *env, int *info, int size, char *fp);
int decode0_BMP(struct DLL_STRPICENV *env, int size, char *fp, int b_type, char *buf, int skip);
/* jpeg.c */
int info_JPEG(struct DLL_STRPICENV *env, int *info, int size, char *fp);
int decode0_JPEG(struct DLL_STRPICENV *env, int size, char *fp, int b_type, char *buf, int skip);
unsigned char rgb2pal(int r, int g, int b, int x, int y);
void error(char *s);
void HariMain(void)
{
struct DLL_STRPICENV env;
char filebuf[512 * 1024], winbuf[1040 * 805];
char s[32], *p;
int win, i, j, fsize, xsize, info[8];
struct RGB picbuf[1024 * 768], *q;
/*命令行解析*/
api_cmdline(s, 30);
for (p = s; *p > ' '; p++) { } /*一直读到空格为止*/
for (; *p == ' '; p++) { } /*跳过空格*/
/*文件载入*/
i = api_fopen(p); if (i == 0) { error("file not found.\n"); }
fsize = api_fsize(i, 0);
if (fsize > 512 * 1024) {
error("file too large.\n");
}
api_fread(filebuf, fsize, i);
api_fclose(i);
/*检查文件类型*/
if (info_BMP(&env, info, fsize, filebuf) == 0) {
/*不是BMP */
if (info_JPEG(&env, info, fsize, filebuf) == 0) {
/*也不是JPEG */
api_putstr0("file type unknown.\n");
api_end();
}
}
/*上面其中一个info函数调用成功的话info中包含以下信息 */
/*info[0]文件类型1:BMP、2:JPEG*/
/*info[1]:颜色数信息*/
/*info[2]xsize */
/* info[3] : ysize */
if (info[2] > 1024 || info[3] > 768) {
error("picture too large.\n");
}
/*窗口准备*/
xsize = info[2] + 16;
if (xsize < 136) {
xsize = 136;
}
win = api_openwin(winbuf, xsize, info[3] + 37, -1, "gview");
/*将文件内容转换为图像数据*/
if (info[0] == 1) {
i = decode0_BMP (&env, fsize, filebuf, 4, (char *) picbuf, 0);
} else {
i = decode0_JPEG(&env, fsize, filebuf, 4, (char *) picbuf, 0);
}
/*b_type = 4表示struct RGB格式*/
/*skip设为0即可*/
if (i != 0) {
error("decode error.\n");
}
/*显示*/
for (i = 0; i < info[3]; i++) {
p = winbuf + (i + 29) * xsize + (xsize - info[2]) / 2;
q = picbuf + i * info[2];
for (j = 0; j < info[2]; j++) {
p[j] = rgb2pal(q[j].r, q[j].g, q[j].b, j, i);
}
}
api_refreshwin(win, (xsize - info[2]) / 2, 29, (xsize - info[2]) / 2 + info[2], 29 + info[3]);
/*等待结束*/
for (;;) {
i = api_getkey(1);
if (i == 'Q' || i == 'q') {
api_end();
}
}
}
unsigned char rgb2pal(int r, int g, int b, int x, int y)
{
static int table[4] = { 3, 1, 0, 2 };
int i;
x &= 1; /*判断是偶数还是奇数*/
y &= 1;
i = table[x + y * 2]; /*用于生成中间色的常量*/
r = (r * 21) / 256; /*结果为020*/
g = (g * 21) / 256;
b = (b * 21) / 256;
r = (r + i) / 4; /*结果为05*/
g = (g + i) / 4;
b = (b + i) / 4;
return 16 + r + g * 6 + b * 36;
}
void error(char *s)
{
api_putstr0(s);
api_end();
}