• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            專注于服務(wù)器編程、網(wǎng)絡(luò)編程

            ~~保持一顆平常心~~持之以恒~~
            posts - 18, comments - 7, trackbacks - 0, articles - 0
              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理
            MTK圖片解碼流程及png圖片詳解(轉(zhuǎn)載)
            2009-12-05 22:21

            從事MTK平臺(tái)的工作者很多,做高仿機(jī)的人也很多,MTK的界面變得越來越花哨,但是對(duì)于MTK平臺(tái)實(shí)現(xiàn)進(jìn)行研究的文章并不多,希望這篇文章和以后的幾篇BLOG能為MTK的初學(xué)者帶來一些幫助。

                  怎么使用MTK的函數(shù)顯示圖片相信大家都會(huì),但是圖片的解碼過程就不是人人都去研究了,由于我們做JVM移植層的需要,最近對(duì)MTK的圖形解碼進(jìn)行了一些研究。

                  MTK在繪制圖形的時(shí)候使用的是gdi_image_codec_draw這個(gè)函數(shù),在這個(gè)函數(shù)中,MTK會(huì)根據(jù)img_type這個(gè)參數(shù)從gdi_image_codecs這個(gè)全局?jǐn)?shù)據(jù)結(jié)構(gòu)數(shù)組中取得相應(yīng)繪制回調(diào)函數(shù)。gdi_image_codecs全局變量在gdi_image.c文件中定義。

                  (1)BMP解析過程

                  當(dāng)img_type為GDI_IMAGE_TYPE_BMP_FILE_OFFSET的時(shí)候,MTK會(huì)調(diào)用gdi_image_bmp_draw_handler作為BMP文件解析的處理函數(shù)。在這個(gè)函數(shù)中,MTK會(huì)根據(jù)程序員指定的顯示大小對(duì)bmp文件進(jìn)行放大或者縮小,由于這里我們只是簡單研究一下,就不以圖片的放大或者縮小為例子了,如果要研究圖片的放大或者縮小,請(qǐng)各位自己研究。我們只研究不對(duì)bmp進(jìn)行放大或者縮小的過程——gdi_image_bmp_draw_file函數(shù)。

                  gdi_image_bmp_draw_file這個(gè)函數(shù)在gdi_image_bmp.c文件中。這個(gè)函數(shù)一開始首先建立了一個(gè)比特流,在我看來就是把這個(gè)BMP文件打開,并把BMP的文件的數(shù)據(jù)放到gdi_bytestream_buffer這個(gè)全局?jǐn)?shù)組中,為以后的解碼做準(zhǔn)備。接下來大家可能就要迷糊了,MTK使用的是gdi_image_bmp_draw_internal_from_file這樣一個(gè)函數(shù),這個(gè)函數(shù)是什么呢!說出來下一條,這個(gè)函數(shù)是個(gè)宏!確切的說這個(gè)曾經(jīng)是函數(shù)調(diào)用的語句實(shí)際上被GDI_IMAGE_BMP_DRAW_INTERNAL這個(gè)宏所替代,而這個(gè)宏在gdi_image_bmp_codec.h中有一個(gè)同名函數(shù),這樣gdi_image_bmp_draw_internal_from_file就被指示成了GDI_IMAGE_BMP_DRAW_INTERNAL。我第一次就暈菜了,搞不懂為什么MTK要費(fèi)這么大勁,繞這么多彎。

                  GDI_IMAGE_BMP_DRAW_INTERNAL就是解碼過程,我們可以看到這里面有1,4,8,16,24,32位BMP的解碼函數(shù),如果我們解碼的不是這些標(biāo)準(zhǔn)的BMP呢!對(duì)不起,MTK會(huì)重啟!

                  (2)靜態(tài)GIF圖片的解碼過程

                  當(dāng)img_type為GDI_IMAGE_TYPE_GIF_FILE_OFFSET的時(shí)候,MTK會(huì)調(diào)用gdi_image_gif_draw_handler函數(shù)進(jìn)行解碼。在這個(gè)函數(shù)中同樣分為可變大小和不可變大小,數(shù)據(jù)來源于文件還是來源與內(nèi)存資源,這4種情況,我們還是只討論數(shù)據(jù)來源于文件而且不進(jìn)行縮放操作的情況——gdi_image_gif_draw_file。

                  gdi_image_gif_draw_file這個(gè)函數(shù)有兩個(gè)分支。在整個(gè)函數(shù)的實(shí)現(xiàn)中,會(huì)有一個(gè)do{}while(0)的循環(huán),在定義了硬件解碼宏之后,在硬件解碼結(jié)束以后使用一個(gè)break;語句跳出循環(huán)。軟解碼的代碼在硬解碼的代碼后面,沒有宏控制。當(dāng)硬解碼宏打開后,完全靠硬解碼結(jié)束后的break來區(qū)分軟硬解碼。這樣,如果硬解碼出現(xiàn)問題,可能會(huì)造成嚴(yán)重的后果。我不清楚MTK為什么這樣做,可能是他們認(rèn)為硬解碼的所有返回都已經(jīng)處理過了,所以才使用這種方式的吧!

                  在6226,6228等高端的MTKCPU上,圖像都是硬解碼的。在這些CPU內(nèi)部有一組專門的解碼電路來對(duì)圖形進(jìn)行解碼。在硬解碼的時(shí)候,MTK最終會(huì)調(diào)用gif_decode_hw這個(gè)函數(shù)對(duì)CPU內(nèi)部的寄存器進(jìn)行相關(guān)的設(shè)置,最后調(diào)用GIF_START這個(gè)宏函數(shù)開始對(duì)GIF圖形進(jìn)行解碼。

                  在6225以下的CPU中,所有的圖像都是軟解碼的,這時(shí)MTK使用了ret = gdi_image_gif_draw_file_decoders[gdi_act_layer->cf] 這個(gè)語句。gdi_image_gif_draw_file_decoders是一個(gè)函數(shù)指針數(shù)組。這個(gè)數(shù)組定義在gdi_image_gif.c中,這個(gè)數(shù)組中的元素(例如gdi_image_gif_draw_internal_from_file_8等)其實(shí)都指向GDI_IMAGE_GIF_DRAW_INTERNAL這個(gè)宏,這個(gè)宏又在Gdi_image_gif_codec.h中對(duì)應(yīng)一個(gè)同名函數(shù)。好像在哪里見過哈!對(duì)!BMP就是這樣指來指去的。MTK的風(fēng)格就是這樣奇怪而統(tǒng)一。

                  GDI_IMAGE_GIF_DRAW_INTERNAL就是GIF的解碼過程。 一開始,MTK向我們展示了一個(gè)catch機(jī)制,MTK把最后的2張GIF圖片保存在一個(gè)gdi_gif_cache的數(shù)據(jù)結(jié)構(gòu)中,首先檢查程序員需要的是不是這兩張圖片。如果是就不用解析了,不是就要重新解析。解析的算法我們就不討論了,喜歡研究的可以看看GDI_IMAGE_GIF_CODEC這個(gè)函數(shù)的實(shí)現(xiàn),GIF由于有動(dòng)畫的設(shè)定,所以解析起來要比BMP復(fù)雜多了!

                  (3)JPEG圖片解碼過程

                  當(dāng)img_type為GDI_IMAGE_TYPE_JPG_FILE_OFFSET的時(shí)候,MTK會(huì)調(diào)用gdi_image_jpeg_draw_handler函數(shù)進(jìn)行解碼。這個(gè)函數(shù)最終會(huì)調(diào)用gdi_image_hwjpeg_draw_internal。MTK把JPEG的軟解碼和硬解碼的接口在這個(gè)函數(shù)層次統(tǒng)一了起來,gdi_image_hwjpeg_draw_internal會(huì)調(diào)用gdi_image_hwjpeg_start_decode,gdi_image_hwjpeg_start_decode再調(diào)用jpeg_decode_process函數(shù)。jpeg_decode_process函數(shù)再負(fù)責(zé)調(diào)用JPEG解碼核心對(duì)JPEG圖片進(jìn)行解碼。最后的解碼函數(shù)為decode_jpeg_file這個(gè)函數(shù)。無論是軟解碼還是硬解碼都要調(diào)用decode_jpeg_file這個(gè)函數(shù)。在JPEG圖形解碼這部分,MTK做的還是比較符合中國工程師習(xí)慣的。

                  還有一點(diǎn),如果我們只想取得JPEG圖像的數(shù)據(jù),那么我們只要調(diào)用gdi_image_jpeg_draw_file_to_buffer或者gdi_image_jpeg_draw_to_buffer這兩個(gè)函數(shù)好了。我們測試過,MTK對(duì)這兩個(gè)函數(shù)的封裝,封裝的比較好。這樣就給了我們一個(gè)通過JPEG圖像傳遞某種信息的渠道。哦!搞的想干壞事一樣,不說了,不說了!

                   (4)PNG圖片解碼過程

                    當(dāng)img_type為GDI_IMAGE_TYPE_PNG_FILE_OFFSET的時(shí)候,MTK會(huì)對(duì)PNG進(jìn)行解碼,經(jīng)過了上面的分析,我相信大家都能對(duì)MTK的圖形解碼的流程有了比較深刻的理解了,各位可以自己分析這個(gè)過程,我這邊就不贅述了!

                  

                    以上我自己是對(duì)MTK圖形解碼過程的大致分析,有不當(dāng)之處還希望大家能夠指正。

                    下一篇BLOG我準(zhǔn)備謝謝如何在MTK平臺(tái)下建立靜態(tài)TASK,以及如何從MMITASK中接管控制權(quán)。這部分很簡單同樣是對(duì)應(yīng)初學(xué)者的,希望老鳥不要拍磚!!!

             

            MTK界面設(shè)計(jì)中消除PNG圖片的雜色背景

            PNG圖片因?yàn)轶w積小,背景可以透明,并且由于采用矢量圖像技術(shù)可以制作無鋸齒的圓角類型的圖形等優(yōu)勢。曾經(jīng)在網(wǎng)頁和一些領(lǐng)域得到廣泛應(yīng)用。近來可能是由于MTK的熱門提供了更多的工作機(jī)會(huì),導(dǎo)致不少以前從事網(wǎng)站創(chuàng)作的美術(shù)人員也轉(zhuǎn)入到手機(jī)行業(yè)。這些同志們?cè)O(shè)計(jì)的UI充斥了大量的PNG圖片。給MTK的MMI工程師提供了不小的挑戰(zhàn)。

            確切的說,我認(rèn)為在MTK手機(jī)平臺(tái)上,PNG并不具有顯著優(yōu)勢。MTK會(huì)把PNG轉(zhuǎn)化為一種BMPA的中間格式,該格式并不比同樣效果的BMP小,有時(shí)還會(huì)大上許多。至于背景透明,其實(shí)在MTK平臺(tái),是可以把一幅BMP顯示為背景透明的。這樣PNG存在的唯一意義大約就在于顯示一些更精致的需要流線型圖像效果的UI里了。而PNG在使用過程中,在某些方面,比如疊加,比如在層中使用,往往會(huì)存在一些顯示效果不盡如人意的地方。這些原因?qū)е略S多MMI工程師不喜歡PNG,除非在非常必要的情況下,否則會(huì)直接到PNG用ASD轉(zhuǎn)為BMP使用。雖然許多時(shí)候我也不建議使用PNG,但有些必要場合,使用PNG畢竟也能為手機(jī)顯示增色不少。

            一次幫客戶設(shè)計(jì)UI時(shí),遇到在層中顯示PNG圖片顯示亂屏,圖的背景有雜色,圖標(biāo)邊緣通透等問題,嚴(yán)重影響了顯示效果。本可轉(zhuǎn)為BMP重新設(shè)計(jì),后來抱著學(xué)習(xí)的態(tài)度搜了一下52RD,竟然有人提供了一個(gè)解決了函數(shù)gdi_image_abm_set_source_layer,后來研究了一下,果然解決了這個(gè)問題。

            附上樣例程序:(由于該層在移動(dòng)過程中只是位置改變,然后刷在屏上,所以沒有把把創(chuàng)建層的代碼與使用代碼分開,圖片IMG_IDLE_TIME_BG為PNG,背景上顯示的字符也為PNG圖片,能夠消除PNG層亂屏雜色問題的函數(shù)是gdi_push_and_set_alpha_blending_source_layer,當(dāng)然gdi_image_abm_set_source_layer也能達(dá)到)
            void DrawDateTimeLayer(U16 x, U16 y)
            {
                   #ifdef WIN32
            buf_ptr = (PU8)malloc(180*61*2);
            #else
            buf_ptr = (PU8)med_alloc_ext_mem(180*61*2);
            #endif

            if (buf_ptr == NULL)
            {
            MMI_ASSERT(0);
            }

            gdi_layer_create_using_outside_memory(
                                                        0,
                                                        0,
                                                        180,
                                                        61,
                                                        &mylayer,
                                                        (PU8) buf_ptr,
                                                        (S32) 180*61*2);

            gdi_layer_push_and_set_active(mylayer);
            gdi_layer_set_position(x, y); //設(shè)置激活層的位置
            gdi_push_and_set_alpha_blending_source_layer(mylayer); //把mylayer層作為blending層
            gdi_layer_clear_background(GDI_COLOR_WHITE);
            gdi_layer_set_source_key(TRUE, GDI_COLOR_WHITE);
            gdi_image_draw_id(x, y, IMG_IDLE_TIME_BG); //繪制時(shí)間背景
            gdi_pop_and_restore_alpha_blending_source_layer();    //恢復(fù)blending層
            gdi_layer_pop_and_restore_active();
            gdi_layer_set_blt_layer(dm_get_wallpaper_layer(), GDI_LAYER_MAIN_BASE_LAYER_HANDLE, mylayer, NULL);
            gdi_layer_blt_previous(0, 0, UI_device_width-1, UI_device_height - 1);
            }

             

             

            樓的朋友,這些函數(shù)25平臺(tái)上是有的,在文件gdi_layer.c中可以看到該函數(shù)實(shí)現(xiàn)過程,如果你看不到gdi_layer.c,可能你所在的單位為保護(hù)代碼外流,對(duì)MTK代碼做了封裝,但應(yīng)該不影響使用。 2樓的朋友,函數(shù)gdi_image_abm_set_source_layer用法與gdi_push_and_set_alpha_blending_source_layer一樣,傳入要設(shè)置層就可以了,不過gdi_image_abm_set_source_layer在設(shè)置新層為alpha_blending_source_layer時(shí)會(huì)返回老的alpha_blending_source_layer層的HAND,你要保存好,使用完后一定要記著把老的層還原。 3樓的朋友的回復(fù)又讓人受益良多,熟悉各種圖像格式的優(yōu)缺點(diǎn)和MTK與之對(duì)應(yīng)的API和處理機(jī)制,對(duì)我們的工作是有莫大好處的。


            3樓 usstwonder 發(fā)表于 2009-6-25 10:39:00
              PNG圖片可以定義alpha通道,有了alpha通道,可以定義每個(gè)像素點(diǎn)的透明度,能做出很炫的圖片效果來。當(dāng)前MTK平臺(tái)的PNG解碼器用的是一個(gè)開源的PNG解碼器:libpng,但是mtk對(duì)libpng進(jìn)行了封裝,在解碼的時(shí)候需要傳入blending層,mtk解碼的時(shí)候,會(huì)跟據(jù)圖片的alpha通道值,自動(dòng)把解碼出來的像素的和blending層的像素進(jìn)去混合疊加,然后把混合疊加后的效果輸出。gdi_push_and_set_alpha_blending_source_layer()是設(shè)置blending層,也就是png解碼時(shí)用來當(dāng)作背景的層。

            97超级碰碰碰碰久久久久| 精品综合久久久久久98| 久久亚洲日韩精品一区二区三区| 久久久久久国产a免费观看不卡| 久久这里只有精品久久| 久久久久中文字幕| 国产91久久综合| 久久不见久久见免费影院www日本| 久久99国产精品一区二区| 国产精品久久自在自线观看| 69久久夜色精品国产69| 久久国产一区二区| 久久97久久97精品免视看| 久久久久九国产精品| 久久人人爽人人爽人人片AV麻烦| 久久夜色精品国产噜噜噜亚洲AV| 97久久国产亚洲精品超碰热| 国内精品久久久久久久影视麻豆| 午夜精品久久影院蜜桃| 久久精品国产99国产精品亚洲| 国内精品综合久久久40p| 久久精品国产亚洲AV高清热| 国产精品99久久久久久www| 亚洲国产成人精品91久久久| 国产69精品久久久久久人妻精品| 久久久久久久人妻无码中文字幕爆 | 久久久国产精华液| 久久婷婷五月综合97色直播| 国产亚洲精久久久久久无码| 一本一道久久精品综合| 精品久久久久久无码不卡| 国产成人精品久久二区二区| 久久亚洲精品国产亚洲老地址 | 色8激情欧美成人久久综合电| 一本久久知道综合久久| 久久久九九有精品国产| 久久久久18| 狠狠久久亚洲欧美专区| 久久免费99精品国产自在现线 | 人人狠狠综合久久88成人| 久久久青草久久久青草|