高通LCD开机图片制作步骤(kernel部分)

1、使用ImageMagick自带的convert命令,进行raw格式转换(convert -depth 8 logo.png rgb:slogo.raw)logo.png是源文件,slogo.raw是转换完成的文件

:imgageMagick安装包,Ubuntu执行sudo apt-get installimagemagick

2
、编译一下android自带的rgb2565工具,其路径在$ANDROID_HOME/build/tools/rgb2565上(gcc -O2 -Wall-Wno-unused-parameter -o rgb2565 to565.c

注:这个工具在\out\host\linux-x86\bin这个目录下已经是编译出来了的。

3
、对raw文件进行rle565格式转换(rgb2565 -rle < slogo.raw >initlogo.rle) 这个地方的<>是必须有的,slogo.raw就是第一步转换出来的文件,initlogo.rle就是转换完成的文件。


上面的步骤是标准的准换过程,我们在网上很容易搜索到。但在显示的时候,有时还是会遇到问题,我们再接着来分析相关的部分。首先是rle文件,下面是某个rle图片文件用UE打开的16进制的数据:


这里的数据以4个字节一组,后两位用rgb565表示的颜色,前面两位表示的当前颜色的像素点,也就是后面紧接着有多少个这样颜色的像素点。注意他们是后一字节是高位,前面字节是低位。所以我们可以通过它知道一幅图片有多少个像素点,就是把所有的个数相加就对了。当我们用第三步来转换的时候,这个程序也会打印出来一个数据,这个就是整幅图片的像素个数了。


那么我们分析rle的目的是什么呢,因为我们现在的LCD基本上都是24位色,也就是RGB888,而我们这里用的是RGB565,这个自然是需要我们把相应的数据填充成为RGB888了。内核里面显示的函数是load_565rle_image(),我们需要对其进行修改:

int load_565rle_image(char *filename, bool bf_supported)
{
	struct fb_info *info;
	int fd, count, err = 0;
	unsigned max;
	unsigned short *data, *bits, *ptr;
    	unsigned int rgb32, red, green, blue, alpha;

	info = registered_fb[0];
	if (!info) {
		printk(KERN_WARNING "%s: Can not access framebuffer\n",
			__func__);
		return -ENODEV;
	}

	fd = sys_open(filename, O_RDONLY, 0);
	if (fd < 0) {
		printk(KERN_WARNING "%s: Can not open %s\n",
			__func__, filename);
		return -ENOENT;
	}
	count = sys_lseek(fd, (off_t)0, 2);
	if (count <= 0) {
		err = -EIO;
		goto err_logo_close_file;
	}
	sys_lseek(fd, (off_t)0, 0);
	data = kmalloc(count, GFP_KERNEL);
	if (!data) {
		printk(KERN_WARNING "%s: Can not alloc data\n", __func__);
		err = -ENOMEM;
		goto err_logo_close_file;
	}
	if (sys_read(fd, (char *)data, count) != count) {
		err = -EIO;
		goto err_logo_free_data;
	}

	max = fb_width(info) * fb_height(info);
	ptr = data;
	if (bf_supported && (info->node == 1 || info->node == 2)) {
		err = -EPERM;
		pr_err("%s:%d no info->creen_base on fb%d!\n",
		       __func__, __LINE__, info->node);
		goto err_logo_free_data;
	}
	bits = (unsigned short *)(info->screen_base);

	while (count > 3) {
		unsigned n = ptr[0];
		if (n > max)
			break;
		if (fb_bpp(info) == 16) {
			memset16(bits, ptr[1], n << 1);
			bits += n;
		} else if (fb_bpp(info) == 32) {  //add for RGB888 display
	        /* convert 16 bits to 32 bits */
	        rgb32 = ((ptr[1] >> 11) & 0x1F);
	        red = (rgb32 << 3) | (rgb32 >> 2);
	        rgb32 = ((ptr[1] >> 5) & 0x3F);
	        green = (rgb32 << 2) | (rgb32 >> 4);
	        rgb32 = ((ptr[1]) & 0x1F);
	        blue = (rgb32 << 3) | (rgb32 >> 2);
	        alpha = 0xff;
	        rgb32 = (alpha << 24) | (blue << 16) | (green << 8) | (red);
	        memset32(bits, rgb32, n << 2);
	        bits += (n * 2);
		}
		max -= n;
		ptr += 2;
		count -= 4;
	}

err_logo_free_data:
	kfree(data);
err_logo_close_file:
	sys_close(fd);
	return err;
}
这里主要就是对上面图片里面展示的RGB扩充到8位,然后显示就可以了。


我么可以采用纯色图片,条纹图片进行显示,根据显示的效果来分析。我自己遇到个显示错位了,后面发现是图像的大小不对应,既然这里是32位,那么图像的宽度应该是32的倍数,我们1080的LCD,这个地方需要1088像素的图片。


如果后面还需要什么问题,继续补充...

你可能感兴趣的:(高通LCD开机图片制作步骤(kernel部分))