一、前言

在前面介绍FrameBuffer子系统曾说过一帧的概念:“我们将铺满一个lcd屏幕的数据称为一帧”。

那么,在每一帧数据中又由许多个像素点构成。

这些像素点就是本文的正题——RGB数据。

所谓RGB数据,就是按照RED、GREEN、BLUE这样顺序排列的图像数据。

而RGB565和RGB888这些英文字母后面的数字则是代表每种颜色的数据占据多少位了,所以RGB565在内存中占据16位,而RGB888在内存中占据24位。

在实际项目中,一些平台因为不支持RGB888,只支持RGB565,所以,在你需要显示RGB888数据格式的图像时,就需要使用一些简单或者复杂的算法,把这些数据转换成RGB888。

如果不进行转换,直接将RGB888图像显示,那么实际展现的效果就差强人意了。原因就是平台不支持RGB888这种24位的数据格式,在显示过程中被当成了RGB565数据格式输出到了LCD。

二、重构fb_show_logo函数

那么,为了解决平台不兼容的问题,根据前言中提到的办法,需要使用算法,将RGB565数据转换成RGB888再输出到FrameBuffer中,继而将图像数据输出到RGB888格式的LCD屏上。

在FrameBuffer子系统中有一个叫做fb_show_logo的函数,用于显示logo,这里我们需要重构它。

1、fb_show_logo

int fb_show_logo(struct fb_info *info, int rotate)
{int y;#ifdef CONFIG_LOGO_LINUX_TRUECOLOR_LOGOfb_show_truecolor_logo(info);return 1;
#endify = fb_show_logo_line(info, rotate, fb_logo.logo, 0,
#ifdef CONFIG_FB_LOGO_CENTERED1);
#elsenum_online_cpus());
#endify = fb_show_extra_logos(info, y, rotate);return y;
}

这里的“#ifdef CONFIG_LOGO_LINUX_TRUECOLOR_LOGO”就是我们重构的内容。

接下来看fb_show_truecolor_logo具体如何实现。

2、fb_show_truecolor_logo

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <asm/uaccess.h>
#include <linux/fb.h>
#include <linux/init.h>//用于数据移位
static inline unsigned safe_shift(unsigned d, int n)
{return n < 0 ? d >> -n : d << n;
}//rgb565转rgb888核心函数
static uint32_t rgb565_to_rgb888(struct fb_info *info,uint16_t rgb565)
{uint32_t rgb888 = 0;static const unsigned char mask[] = { 0,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff };unsigned char redmask, greenmask, bluemask,transpmask;unsigned int redshift, greenshift, blueshift,transpshift;unsigned char red   = 0;  // 5-bit redunsigned char green = 0;  // 6-bit greenunsigned char blue  = 0;  // 5-bit blueunsigned char transp = 0;  /*transp主要就是用于移位之后做565和888之间的数据补充,避免有色差,但实际上,下面对transp赋值为0,所以这里只是一个用0填补空位的作用*/redmask   = mask[info->var.red.length   < 8 ? info->var.red.length   : 8];greenmask = mask[info->var.green.length < 8 ? info->var.green.length : 8];bluemask  = mask[info->var.blue.length  < 8 ? info->var.blue.length  : 8];transpmask = mask[info->var.transp.length  < 8 ? info->var.transp.length  : 8];redshift   = info->var.red.offset   - (8 - info->var.red.length);greenshift = info->var.green.offset - (8 - info->var.green.length);blueshift  = info->var.blue.offset  - (8 - info->var.blue.length);transpshift  = info->var.transp.offset  - (8 - info->var.transp.length);// 获取RGB单色并填充低位red = ((rgb565 >> 11) & 0x1F) << 3;green = ((rgb565 >> 5) & 0x3F) << 2;blue = (rgb565 & 0x1F) << 3;transp = 0x00;rgb888 = (safe_shift((red & redmask), redshift) |safe_shift((green & greenmask), greenshift) |safe_shift((blue & bluemask), blueshift) | safe_shift((transp & transpmask), transpshift) );return rgb888;
}void fb_show_truecolor_logo(struct fb_info *info)
{int i,j;//这里的地址就是显存的地址unsigned int* addr = (unsigned int*)info->screen_base;int xres,yres;int offset_x,offset_y;int bits_per_pixel;uint16_t rgb565;const uint8_t *clut = (const uint8_t *)truecolor_logo_data;xres = info->var.xres;yres = info->var.yres;bits_per_pixel = info->var.bits_per_pixel;if(xres > LOGO_WIDTH)offset_x = (xres - LOGO_WIDTH)/2;elseoffset_x =  0;if(yres > LOGO_HEIGHT)offset_y = (yres - LOGO_HEIGHT)/2;elseoffset_y = 0;pr_emerg("%s xres=%d yres=%d offset_x=%d offset_y=%d\n",__func__,xres,yres,offset_x,offset_y);//为什么这里是32位呢?因为这里用的是rgba,a是透明度,所以每个像素有32位if(bits_per_pixel == 32){for (i = 0; i < LOGO_HEIGHT; i++){for(j = 0;j < LOGO_WIDTH;j++){#if 1rgb565 = clut[i*LOGO_WIDTH*2+j*2] | (clut[i*LOGO_WIDTH*2 + j*2 + 1] << 8);// rgb565->rgb888addr[offset_x + j + (i + offset_y) * xres ] = rgb565_to_rgb888(info,rgb565);#elsergb565 = clut[i*LOGO_WIDTH*2+j];addr[offset_x + j + (i + offset_y) * xres ] = rgb565;#endif}}}else{   }
}

Linux驱动开发之RGB565转RGB888相关推荐

  1. Linux驱动开发之platform设备驱动实验【完整教程】

    为了方便驱动的编写,提高软件的重用性和跨平台性能,于是就提出了Linux驱动的分离和分层   驱动的分层,分层的目的时为了在不同的层处理不同的内容,最简单的驱动分层是input子系统负责管理所有跟输入 ...

  2. ㉓AW-H3 Linux驱动开发之mipi camera(CSI)驱动程序

    本次说一下mipi camera的驱动开发,平台用的是全志的H3芯片,项目代号:sun8iw7p1,这次使用运行在H3上面的Ubuntu进行验证的. Linux代码:https://github.co ...

  3. ⑭tiny4412 Linux驱动开发之cpufreq子系统驱动程序

    本次我们来说一下CPU动态调频子系统. 首先来看一下三星Exynos 4412的datasheet,如下: 上图就是Exynos 4412的时钟分布图,可以看到CPU的频率可以在1.4GHz~200M ...

  4. linux驱动开发之spi-omap-100k.c源码分析

    代码分析 对于linux的驱动代码来说,我们要从后往前分析: /** OMAP7xx SPI 100k controller driver* Author: Fabrice Crohas <fc ...

  5. ⑨tiny4412 Linux驱动开发之1-wire子系统(DS18B20)驱动程序

    本来这次想做LCD背光灯的调节的,但是没有调通,时间很紧迫,就转向了其它东西,昨天调了一下DHT11,今天又调了一下DS18B20,还算有个安慰,本来是想用1-wire子系统做的,但是时间上有点紧,要 ...

  6. Linux驱动开发之IIC驱动实验【完整教程】

    本实验基于正点原子ALPHT开发板上的AP3216C作为实验开展对象 基础知识 1.IIC总线驱动   IIC总线驱动是对IIC硬件体系结构中适配器端的实现,适配器可由CPU控制,甚至可以直接集成在C ...

  7. ㉕AW-A33 Linux驱动开发之audio子系统驱动程序

    在Linux源码里,Aduio这一部分现在是一个独立文件夹叫sound,在2.x的版本时,sound这个目录是在drivers里的,后来从这个里面剥离出来了,很多人不知道其中的原因,我也不知道,我们先 ...

  8. Linux驱动开发之USB驱动深入学习(三)——USB2.0ECHI驱动注册

    一.前言 本篇博客仅对ECHI主机控制器驱动的注册部分进行简要叙述,后面再对一些重要的接口进行分析讲解. 二.USB 1.概述 USB(Universal Serial Bus)即"通用外部 ...

  9. linux编译input驱动,Linux驱动开发之input子系统

    本文对mousedev.Amimouse和input子系统进行分析,旨在提纲挈领,给出它们之间的调用关系(或者说关联).阅读本文,需要与阅读Linux 2.6内核源码交叉进行,除非你是超人. 背景: ...

最新文章

  1. python进阶书籍的推荐-Python 入门到进阶书籍推荐
  2. 典型用户描述及进一步需求分析
  3. AngularJS table 按照表头字段排序功能(升序和降序)
  4. linux wheel组
  5. VTK:Texture之TextureCutSphere
  6. rem 前端字体_web前端入门到实战:一次搞懂CSS字体单位:px、em、rem和%
  7. 窗体控件绑定数组 c# 1613698204
  8. 舍弃Python,为什么知乎选用Go重构推荐系统?
  9. 递归:若函数包含了对其自身的调用,该函数为递归的。《Python核心编程》P305...
  10. 优秀程序设计的原则(可以多读读)
  11. 用简单Mask分类实现语义分割、实例分割“大一统”!FacebookUIUC开源MaskFormer
  12. 蓝牙网络共享linux,在Linux系统上安装Blueman以通过蓝牙共享文件
  13. 2022最新7个开源Kubernetes(k8s)开发工具
  14. Edge地址栏搜索引擎换成Bing
  15. MATLAB实现非线性动态范围调整算法
  16. JOIN连接:LEFT OUTER JOIN
  17. 云场景实践研究第62期:华栖云
  18. (六)Flutter 基础部件 TextView 和TextStyle Flutter 容器 装饰盒子 边框 圆角 阴影 形状 渐变 背景图像
  19. 纯css实现涟漪效果
  20. MySQL SQL语句 生成32位 UUID

热门文章

  1. 收集的一些GIS数据网站
  2. 与其自怨自艾,不如夯实勤奋
  3. 微信小程序---家庭记账本开发(一)
  4. Win11如何给应用换图标?Win11给应用换图标的方法
  5. 计算机毕业设计JAVA高校体育场馆预约管理系统设计与实现mybatis+源码+调试部署+系统+数据库+lw
  6. 2023美国大学生数学建模竞赛资料及思路
  7. Point1:STM32根据BRR反推波特率
  8. python-函数(function)
  9. 上拉电阻和下拉电阻判断
  10. Python到pyspark中的py-files的问题