U-Boot_bmp_logo_hacking
/***********************************************************************
* U-Boot_bmp_logo_hacking
* 声明:
* 1. 该源代码来自myzr_android4_2_2_1_1_0.tar.bz2中的:
* bootable/bootloader/uboot-imx/tools/bmp_logo.c
* 2. 通过阅读该源码可以知道大致如何解析bmp图片,以及一些自动生成
* 的文件是如何做到的,如一些自动生成.h和.c文件;
* 3. 阅读该源码技能需求:
* 1. bmp图片的格式的一些基本信息;
* 2. 类Unix系统编程;
* 3. C语言;
* 4. 本源程序的阅读技巧:
* 1. 本人是用了vim + ctags;
* 2. 如果您是在windows下,传说中是可以是用Source Insight;
* 3. 找main函数开始阅读;
*
* 2015-4-19 周日 晴 深圳 南山 西丽平山村 曾剑锋
**********************************************************************/ /**
* 源程序中仅仅是用了#include "compiler.h",由于我们仅仅需要本文件,
* 所以本人注释了那一行,添加以下本文件需要用到的头文件
*/
//#include "compiler.h"
#include <errno.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h> /**
* 用于大致描述一个bmp图片的结构体
*/
typedef struct bitmap_s { /* bitmap description */
uint16_t width;
uint16_t height;
uint8_t palette[*];
uint8_t *data;
} bitmap_t; /**
* 默认的颜色映射的大小
*/
#define DEFAULT_CMAP_SIZE 16 /* size of default color map */ /*
* Neutralize little endians.
* bmp图片用的好象是小端的存储方式
*/
uint16_t le_short(uint16_t x)
{
uint16_t val;
uint8_t *p = (uint8_t *)(&x); val = (*p++ & 0xff) << ;
val |= (*p & 0xff) << ; return val;
} /**
* 在文件的当前位置,偏移多少个字节
*/
void skip_bytes (FILE *fp, int n)
{
while (n-- > )
fgetc (fp);
} /**
* 错误输出函数,输出到标准错误输出
*/
__attribute__ ((__noreturn__))
int error (char * msg, FILE *fp)
{
fprintf (stderr, "ERROR: %s\n", msg); fclose (fp); exit (EXIT_FAILURE);
} int main (int argc, char *argv[])
{
/**
* 局部变量说明:
* 1. i : for循环计数;
* 2. x : 字符暂存变量,for循环计数;
* 3. fp : 打开的bmp文件指针;
* 4. bmp : 用于存储bmp一些数据的数据结构;
* 5. b : 指向上面bmp数据结构的指针;
* 6. data_offset : bmp数据区相对文件头的偏移;
* 7. n_colors : 实际使用了多少种颜色
*/
int i, x;
FILE *fp;
bitmap_t bmp;
bitmap_t *b = &bmp;
uint16_t data_offset, n_colors; /**
* 命令行参数个数检查
*/
if (argc < ) {
fprintf (stderr, "Usage: %s file\n", argv[]);
exit (EXIT_FAILURE);
} /**
* 以二进制只读的方式打开bmp文件
*/
if ((fp = fopen (argv[], "rb")) == NULL) {
perror (argv[]);
exit (EXIT_FAILURE);
} /**
* 检查是否是bmp图片
*/
if (fgetc (fp) != 'B' || fgetc (fp) != 'M')
error ("Input file is not a bitmap", fp); /*
* read width and height of the image, and the number of colors used;
* ignore the rest
*/
/**
* 前面的'B','M'占用了2个字节,
* 2字节 + 8字节 = 10字节,
* 这时文件指针正好指向11字节(保存bmp数据偏移的位置)
*/
skip_bytes (fp, );
if (fread (&data_offset, sizeof (uint16_t), , fp) != )
error ("Couldn't read bitmap data offset", fp);
skip_bytes (fp, ); /**
* 前面的'B','M'占用了2个字节,
* 2字节 + 8字节 = 10字节,
* 10字节 + 2字节 = 12字节,
* 12字节 + 6字节 = 18字节,
* 这时文件指针正好指向19字节(保存bmp宽的位置)
*/
if (fread (&b->width, sizeof (uint16_t), , fp) != )
error ("Couldn't read bitmap width", fp);
skip_bytes (fp, ); /**
* 前面的'B','M'占用了2个字节,
* 2字节 + 8字节 = 10字节,
* 10字节 + 2字节 = 12字节,
* 12字节 + 6字节 = 18字节,
* 18字节 + 2字节 = 20字节,
* 20字节 + 2字节 = 22字节,
* 这时文件指针正好指向23字节(保存bmp高的位置)
*/
if (fread (&b->height, sizeof (uint16_t), , fp) != )
error ("Couldn't read bitmap height", fp);
skip_bytes (fp, ); /**
* 前面的'B','M'占用了2个字节,
* 2字节 + 8字节 = 10字节,
* 10字节 + 2字节 = 12字节,
* 12字节 + 6字节 = 18字节,
* 18字节 + 2字节 = 20字节,
* 20字节 + 2字节 = 22字节,
* 22字节 + 2字节 = 24字节,
* 24字节 + 22字节 = 46字节,
* 这时文件指针正好指向47字节(保存bmp图实际是用的颜色数)
* skip_bytes (fp, 6); --> 跳出位图信息头
*/
if (fread (&n_colors, sizeof (uint16_t), , fp) != )
error ("Couldn't read bitmap colors", fp);
skip_bytes (fp, ); /*
* Repair endianess.
* 防止数据出现大小不兼容的问题
*/
data_offset = le_short(data_offset);
b->width = le_short(b->width);
b->height = le_short(b->height);
n_colors = le_short(n_colors); /* assume we are working with an 8-bit file */
/**
* 防止颜色数太小,或太大
*/
if ((n_colors == ) || (n_colors > - DEFAULT_CMAP_SIZE)) {
/* reserve DEFAULT_CMAP_SIZE color map entries for default map */
n_colors = - DEFAULT_CMAP_SIZE;
} /**
* 打印出一些注释信息和宏定义数据
*/
printf ("/*\n"
" * Automatically generated by \"tools/bmp_logo\"\n"
" *\n"
" * DO NOT EDIT\n"
" *\n"
" */\n\n\n"
"#ifndef __BMP_LOGO_H__\n"
"#define __BMP_LOGO_H__\n\n"
"#define BMP_LOGO_WIDTH\t\t%d\n"
"#define BMP_LOGO_HEIGHT\t\t%d\n"
"#define BMP_LOGO_COLORS\t\t%d\n"
"#define BMP_LOGO_OFFSET\t\t%d\n"
"\n",
b->width, b->height, n_colors,
DEFAULT_CMAP_SIZE); /* allocate memory */
/**
* 采用内存分配的方式,获取data的存储空间
*/
if ((b->data = (uint8_t *)malloc(b->width * b->height)) == NULL)
error ("Error allocating memory for file", fp); /* read and print the palette information */
/**
* 以下是一个输出结果示例:
* unsigned short bmp_logo_palette[] = {
* 0x0FFF, 0x0DDE, 0x026B, 0x026B, 0x0FFF, 0x0FFF, 0x048C, 0x026B,
* 0x026B, 0x0BDE, 0x047C, 0x027B, 0x09BE, 0x026B, 0x0EEF, 0x037B,
* 0x08AD, 0x0DEF, 0x027B, 0x069D, 0x0CDE, 0x0ACE, 0x08BD, 0x07AD,
* 0x027B, 0x058C, 0x037B, 0x0CDE, 0x06AD, 0x037C,
* };
*/
printf ("unsigned short bmp_logo_palette[] = {\n"); for (i=; i<n_colors; ++i) {
b->palette[(int)(i*+)] = fgetc(fp); //个人查资料认为是blue
b->palette[(int)(i*+)] = fgetc(fp); //个人查资料认为是green
b->palette[(int)(i*+)] = fgetc(fp); //个人查资料认为是red
x=fgetc(fp); /**
* 输出的结果正好和读出来的结果相反,主要是因为
* 读取时,后面的高位,输出时先输出的是高位
* 另外这里还考虑到格式化对齐的问题,主要是
* 方便阅读输出的数据.
*/
printf ("%s0x0%X%X%X,%s",
((i%) == ) ? "\t" : " ",
(b->palette[(int)(i*+)] >> ) & 0x0F,
(b->palette[(int)(i*+)] >> ) & 0x0F,
(b->palette[(int)(i*+)] >> ) & 0x0F,
((i%) == ) ? "\n" : ""
);
} /* seek to offset indicated by file header */
/**
* 感觉这行代码不应该放这里,应该放到下面2行后面去比较合理
*/
fseek(fp, (long)data_offset, SEEK_SET); /* read the bitmap; leave room for default color map */
printf ("\n");
printf ("};\n"); printf ("\n"); /**
* 1. 以下是输出结果示例:
* unsigned char bmp_logo_bitmap[] = {
* 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
* 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
* ......
* 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
* 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
* }
* 2. 位图数据记录顺序是在扫描行内是从左到右,扫描行之间是从下到上,
* Windows规定一个扫描行所占的字节数必须是4的倍数,不足以0填充;
* 3. i = (b->height-1)*b->width : 相当于跳到数组的左下脚
*/
printf ("unsigned char bmp_logo_bitmap[] = {\n");
for (i=(b->height-)*b->width; i>=; i-=b->width) {
for (x = ; x < b->width; x++) {
b->data[(uint16_t) i + x] = (uint8_t) fgetc (fp) \
+ DEFAULT_CMAP_SIZE; //不知道这里为什么需要加这个参数
}
}
fclose (fp); /**
* 输出bmp数据
*/
for (i=; i<(b->height*b->width); ++i) {
if ((i%) == )
putchar ('\t');
printf ("0x%02X,%c",
b->data[i],
((i%) == ) ? '\n' : ' '
);
}
printf ("\n"
"};\n\n"
"#endif /* __BMP_LOGO_H__ */\n"
); return ();
}
随机推荐
- Win7下怎么设置让远程桌面连接记住密码下次登录不需再输入
远程桌面连接功能想必大家都不会陌生吧,特别是使用VPS服务器的用户们经常会用到,为了服务器的安全每次都会把密码设置的很复制,但是这样也有一个麻烦,就是每次要桌面远程连接的时候都要输入这么复杂的密码,很 ...
- C/C++UNION中包含STRUCT
测试环境:Win7x64,cn_visual_studio_2010_ultimate_x86_dvd_532347.iso,qt-opensource-windows-x86-msvc2010_op ...
- Bate冲刺四——《WAP团队》
β冲刺第四天 1. 今日完成任务情况以及遇到的问题. ①马麒.杜有海:记录功能完善情况 ②郝明宇:记录验收情况 ③马宏伟.周欣:后台前端数据连接 ④乌勒扎:综合测试 2.成员时间贡献 成员 马宏 ...
- 《Blue_Flke》 团队项目用户验收评审
一.beta冲刺 beta冲刺第一.二天:https://www.cnblogs.com/ruanjgc/p/9226434.html beta冲刺第三天:https://www.cnblogs.co ...
- 雷林鹏分享:Ruby 环境变量
Ruby 环境变量 Ruby 解释器使用下列环境变量来控制它的行为.ENV 对象包含了所有当前设置的环境变量列表. 变量描述 DLN_LIBRARY_PATH动态加载模块搜索的路径. HOME当没有参 ...
- ArcGIS 要素闪烁
ArcGIS 要素闪烁 通过双击要素图例,闪烁定位到要素,并且闪烁一段时间: IFeatureLayer featureLayer = layer as IFeatureLayer; ...
- JS-Object(2) 原型对象 ,prototype属性。
基础✅ prototype(✅) JS中的继承 使用JSON数据 构建对象实战 基础 关键字"this"指向了当前代码运行时的对象( 原文:the current object t ...
- codeforces 559a//Gerald's Hexagon// Codeforces Round #313(Div. 1)
题意:面积是sqrt(3)/4的多少倍? 做延长线 #pragma comment(linker,"/STACK:1024000000,1024000000") #include& ...
- HDU-1232 畅通工程 (并查集、判断图中树的棵数)
Description 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇.省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相 ...
- Oracle 账户锁定问题解决办法
1 打开 SQL PLUS 2 登录数据库 3 输入 conn/as sysdba; 4 输入 alter user 数据库名 account unlock;