Add

MTK平台图片解码方法教程


MTK在绘制图形的时候使用的是gdi_image_codec_draw这个函数,在这个函数中,MTK会根据img_type这个参数从gdi_image_codecs这个全局数据结构数组中取得相应绘制回调函数。gdi_image_codecs全局变量在gdi_image.c文件中定义。

(1)BMP解析过程

当img_type为GDI_IMAGE_TYPE_BMP_FILE_OFFSET的时候,MTK会调用gdi_image_bmp_draw_handler作为BMP文件解析的处理函数。在这个函数中,MTK会根据程序员指定的显示大小对bmp文件进行放大或者缩小,由于这里我们只是简单研究一下,就不以图片的放大或者缩小为例子了,如果要研究图片的放大或者缩小,请各位自己研究。我们只研究不对bmp进行放大或者缩小的过程——gdi_image_bmp_draw_file函数。

gdi_image_bmp_draw_file这个函数在gdi_image_bmp.c文件中。这个函数一开始首先建立了一个比特流,在我看来就是把这个BMP文件打开,并把BMP的文件的数据放到gdi_bytestream_buffer这个全局数组中,为以后的解码做准备。接下来大家可能就要迷糊了,MTK使用的是gdi_image_bmp_draw_internal_from_file这样一个函数,这个函数是什么呢!说出来下一条,这个函数是个宏!确切的说这个曾经是函数调用的语句实际上被GDI_IMAGE_BMP_DRAW_INTERNAL这个宏所替代,而这个宏在gdi_image_bmp_codec.h中有一个同名函数,这样gdi_image_bmp_draw_internal_from_file就被指示成了GDI_IMAGE_BMP_DRAW_INTERNAL。我第一次就晕菜了,搞不懂为什么MTK要费这么大劲,绕这么多弯。

GDI_IMAGE_BMP_DRAW_INTERNAL就是解码过程,我们可以看到这里面有1,4,8,16,24,32位BMP的解码函数,如果我们解码的不是这些标准的BMP呢!对不起,MTK会重启!

(2)静态GIF图片的解码过程

当img_type为GDI_IMAGE_TYPE_GIF_FILE_OFFSET的时候,MTK会调用gdi_image_gif_draw_handler函数进行解码。在这个函数中同样分为可变大小和不可变大小,数据来源于文件还是来源与内存资源,这4种情况,我们还是只讨论数据来源于文件而且不进行缩放操作的情况——gdi_image_gif_draw_file。

gdi_image_gif_draw_file这个函数有两个分支。在整个函数的实现中,会有一个do{}while(0)的循环,在定义了硬件解码宏之后,在硬件解码结束以后使用一个break;语句跳出循环。软解码的代码在硬解码的代码后面,没有宏控制。当硬解码宏打开后,完全靠硬解码结束后的break来区分软硬解码。这样,如果硬解码出现问题,可能会造成严重的后果。我不清楚MTK为什么这样做,可能是他们认为硬解码的所有返回都已经处理过了,所以才使用这种方式的吧!

在6226,6228等高端的MTKCPU上,图像都是硬解码的。在这些CPU内部有一组专门的解码电路来对图形进行解码。在硬解码的时候,MTK最终会调用gif_decode_hw这个函数对CPU内部的寄存器进行相关的设置,最后调用GIF_START这个宏函数开始对GIF图形进行解码。

在6225以下的CPU中,所有的图像都是软解码的,这时MTK使用了ret = gdi_image_gif_draw_file_decoders[gdi_act_layer->cf] 这个语句。gdi_image_gif_draw_file_decoders是一个函数指针数组。这个数组定义在gdi_image_gif.c中,这个数组中的元素(例如gdi_image_gif_draw_internal_from_file_8等)其实都指向GDI_IMAGE_GIF_DRAW_INTERNAL这个宏,这个宏又在Gdi_image_gif_codec.h中对应一个同名函数。好像在哪里见过哈!对!BMP就是这样指来指去的。MTK的风格就是这样奇怪而统一。

GDI_IMAGE_GIF_DRAW_INTERNAL就是GIF的解码过程。 一开始,MTK向我们展示了一个catch机制,MTK把最后的2张GIF图片保存在一个gdi_gif_cache的数据结构中,首先检查程序员需要的是不是这两张图片。如果是就不用解析了,不是就要重新解析。解析的算法我们就不讨论了,喜欢研究的可以看看GDI_IMAGE_GIF_CODEC这个函数的实现,GIF由于有动画的设定,所以解析起来要比BMP复杂多了!

(3)JPEG图片解码过程

当img_type为GDI_IMAGE_TYPE_JPG_FILE_OFFSET的时候,MTK会调用gdi_image_jpeg_draw_handler函数进行解码。这个函数最终会调用gdi_image_hwjpeg_draw_internal。MTK把JPEG的软解码和硬解码的接口在这个函数层次统一了起来,gdi_image_hwjpeg_draw_internal会调用gdi_image_hwjpeg_start_decode,gdi_image_hwjpeg_start_decode再调用jpeg_decode_process函数。jpeg_decode_process函数再负责调用JPEG解码核心对JPEG图片进行解码。最后的解码函数为decode_jpeg_file这个函数。无论是软解码还是硬解码都要调用decode_jpeg_file这个函数。在JPEG图形解码这部分,MTK做的还是比较符合中国工程师习惯的。

还有一点,如果我们只想取得JPEG图像的数据,那么我们只要调用gdi_image_jpeg_draw_file_to_buffer或者gdi_image_jpeg_draw_to_buffer这两个函数好了。我们测试过,MTK对这两个函数的封装,封装的比较好。这样就给了我们一个通过JPEG图像传递某种信息的渠道。哦!搞的想干坏事一样,不说了,不说了!

(4)PNG图片解码过程

当img_type为GDI_IMAGE_TYPE_PNG_FILE_OFFSET的时候,MTK会对PNG进行解码,经过了上面的分析,我相信大家都能对MTK的图形解码的流程有了比较深刻的理解了,各位可以自己分析这个过程,我这边就不赘述了

  • http://www.zgcyz.cn 菜园子

    博主写的非常好 顶

Random Posts Recent Comments

  • 女友糖尿病害我蛀牙 Says:

    汗一个…...

  • Htj06 Says:

    zhenyouchuangyi...

  • 电商圈 Says:

    试图该怎么建立啊,,怎在程序中是吸纳...

  • edward Says:

    看得人心旷神怡,好文,情不自禁的顶一下...

  • Daniel Says:

    我也在处理这个问题,没有找到好的方法。我用了楼上兄弟的方法,还是可以的。不知道您找到好的方法了吗、我暂时楼上兄弟的方法。...

  • 卡,卡 Says:

    弱弱问一句:博主,你博客的模板这样设计pv高吗?...

  • 站长工具 Says:

    博主,兔年快乐!...

  • health Says:

    great post!!I hope I can read more in your website....

  • pdu Says:

    好博文,支持分享...

  • 站长工具 Says:

    博主的文章很不错,我是站长工具-站长精灵的作者,一款专业的SEO工具软件(可以帮您提高博客的流量),想跟您交换个链接,不知可否...

Tag Cloud

arm audio blog brew cache class debug flash google html j2me java javascript Joke linux lua mobile mtk php python ror ruby server shell stream unix web windows 优化 动态加载 女人 女生 平台 开发 手机 技术 流媒体 测试 漫画 生活 男人 男生 缓存 芯片