1. <tt id="5hhch"><source id="5hhch"></source></tt>
    1. <xmp id="5hhch"></xmp>

  2. <xmp id="5hhch"><rt id="5hhch"></rt></xmp>

    <rp id="5hhch"></rp>
        <dfn id="5hhch"></dfn>

      1. DOS真彩色模式下真彩色圖像顯示技術

        時間:2024-05-06 07:09:27 計算機畢業論文 我要投稿
        • 相關推薦

        DOS真彩色模式下真彩色圖像顯示技術

        摘要 該文通過介紹Cirrus GD5434卡等幾種高、真彩色卡及其顯示模式,詳述了DOS環境下與硬件無關的VESA高彩色仿真真彩色、真彩色圖像全息顯示的一般性方法,還提示了24位PCX真彩色圖像解壓縮快速顯示編程的要點。最后給出C語言編程示例。

        一、高、真彩色顯示卡
        近年來,順應CAD、CG及多媒體技術進步的要求,許多彩色適配器板卡廠商先后推出性能價格比較高的一系列高彩色(High Color)和真彩色(True Color)SuperVGA顯示卡。如Trident Microsystems公司的TGUI94XX、TGUI96XX,Cirrus Logic的GD543X、GD544X,Tseng Laboratories的ET4000, ARK Logic的ARK1000,、ARK2000,S3 Incorporated的 S3 86CXXX等等。它們除了繼續支持標準VGA模式外,都支持16色、256色、32K高彩色、64K高彩色及16.7M真彩色VESA BIOS 擴展模式,版本大多為VESA 1.2, 卡上具有32K、64K及16.7M DAC,有16位ISA、32位VESA、32位 PCI總線等多種接口,顯示VRAM配置一般有1M、2M、4M,一般都帶有硬件加速的32位或64位圖形加速引擎(Graphics Engine),滿足了當今386~586各種檔次的PC機對更多色彩、更高分辨率的要求。
        表1整理了市場上常見的GD5434(64位GUI)、TGUI9440AGi(32位GUI)和ARK2000PV(64位GUI)三種PCI總線高、真彩色顯示卡的OEM BIOS調用模式號、色彩數、分辨率、VESA模式對照及其相應的VRAM占用等數據。其他支持 VESA 1.2的顯示卡只要查閱卡附手冊得到OEM(原始設備制造商)自定義的高、真彩色模式號或其對應的VESA模式號。有些配4M VRAM的顯示卡甚至可支持1280×1024 16M色(VESA 1.2 11BH模式)。
        表1

        二、高、真彩色編程與256色編程的異同
        高、真彩色模式編程在寫視頻緩沖區端口索引號、頁切換方式、置模式號等方面類同擴展256色編程,例如,Trident的高、真彩色顯示卡,寫視頻緩沖區端口索引號仍是(0x3C4, 0xE)和(0x3C5, page^2),視頻窗口頁粒度仍是64, 頁切換方式仍是64K 頁、128K頁任選。不同點在于:高、真彩色模式已經不再使用256組DAC寄存器索引號及調色板概念,而使用像素字長的RGB 分量數據直接描述色彩及飽和度,寫視頻緩沖區映射到VRAM后由新的64K DAC或16M DAC將色彩數據轉為模擬信號送多頻彩色顯示器,256 色編程中有關調色板的BIOS中斷全部失去作用;其次,由于用多個字節表示一個像素,高、真彩色DAC 轉換的時間成倍增加,顯示速度過分依賴卡上圖形引擎(Graphics Engine)的效率,再加上數據成倍占用RAM或VRAM,所以顯示速度明顯慢于256色圖像顯示。
        另外,不同廠商自定義的訪問端口寄存器索引號的方式均各不相同,直接根據硬件特性的編程必然缺乏通用性。若按照這些顯示適配卡都支持的 VESA ( VideoElectronics Standards Association)標準擴展BIOS功能調用接口編程,從而實現軟件接口層次上的兼容性,所編程序便可在眾多的Super VGA卡上運行,有關 VESA編程的詳細資料請查閱有關書刊。
        表2是高、真彩色像素的分量結構示意,是理解高、真彩色圖像編程的關鍵。
        表2

        三、24位PCX圖像格式簡介
        24位PCX圖像的文件頭同16色、256色的一樣,共128字節, 其中每個像素所用的彩色位數(bit-perpixel)值為8,彩色平面數(color-planes)值為3, 不再使用調色板。24位PCX圖像數據的存儲仍采用有限行程壓縮法,但卻是把單個的RGB行作為三個位平面數據分別進行壓縮存放,第一個位平面由該行所有紅色像素組成;第二個位平面由該行所有綠色像素組成;第三個位平面由該行所有藍色像素組成,因為行程編碼方法并不是總能減小24位復雜圖像的大小,所以對24位PCX 文件進行解碼得到的結果圖像比原來的小也屬正常。本文所用24 位PCX 文件格式符合PCPaintbrush Version 5標準,是從Photo Styler 1.0的TIF圖例轉換的。
        將上述解壓縮的數據用于顯示時,需按顯示卡硬件高、真彩色DAC送色彩信號的順序--紅綠藍紅綠藍......--重新組織,才能正確地顯示24位真彩色圖像。這一點是最不同于其他用三字節行程編碼的24位RGB真彩色圖像(如24位TGA)。其它格式24位的真彩色圖像文件只是圖像頭處理及解壓數據的方式不同,顯示的原理則完全相同。文后所附例程作適當改變,就可用于24位TIF、24位BMP、24位TGA 等圖像文件的顯示。
        下面就640X480分辨率介紹32K、64K高彩色、16M真彩色模式顯示24位PCX圖像。

        四、32K、64K高彩色仿真16M真彩色編程
        現成的64K色圖像很少,彩色掃描儀掃出的多為256色或24位真彩色, 許多圖像處理軟件包的圖例也是同樣情形。這里只好用24位真彩色圖像經下述圖示過程的位移合并,做成16位的64K高彩色像素字。這種取24位RGB分量高位的方法仿真顯示真彩色圖像,明亮部分的色彩層次能較好還原,低暗部分的色彩層次有微小損失,仿真效果很好。讀者也可根據需要作其他位的取舍(如舍兩頭留中間),以使色彩還原最小失真。

        圖示中的空格為零。32K 高彩色仿真與此類似,只需將綠色分量也右移3位,與紅色、藍色分量一道做成最高位為零,低15位有效的一個字,送視頻緩沖區便可。
        具體編程要點如下:

        1.調用VESA BIOS 4f02H 號功能置高彩色圖形模式,成功后調用VESA BIOS4f01H號功能返回每線字節數Line-bytes及窗口頁粒度Wingran等重要參數;

        2.讀圖像頭后直接讀圖像數據,按上述方法轉換為一16位字后送視頻緩沖區始址A000:0000,每一像素一個字,每送一個字到視頻緩沖區,地址偏移量加2;

        3.640×480分辨率下每根掃描線需1280字節,為提高顯示速度,由Line-bytes預先算出每根掃描線始址存于addr數組備查,由于滿屏需600K字節,故編程上仍需考慮切換VRAM頁的情況。例程根據各種卡不同模式的窗口頁粒度Wingran值,調用VESA BIOS 4f05H號功能訪問硬件分頁寄存器實現64K頁模式切換(此時仍有一根掃描線跨兩頁的情形);

        4.顯示完畢,調用VESA BIOS 4f02H 號功能置模式03H恢復原文本模式。

        五、16M真彩色編程
        真彩色編程的關鍵是要了解圖像數據的存放順序及解壓方法,其次注意讀圖像數據后按順序要求作轉換,否則圖像色彩失真。其余過程同高彩色模式。
        具體編程要點如下:

        1.調用VESA BIOS 4F02H號中斷置真彩色圖形模式;成功后調用VESA BIOS4F01H號功能,返回每線字節數Line-bytes及窗口頁粒度Wingran等重要參數;

        2.讀圖像文件頭后直接讀圖像數據,解壓縮后按紅綠藍順序送視頻緩沖區始址A000:0000,每一像素三字節,每送一像素到視頻緩沖區,地址偏移量加3;

        3.在VESA 112H模式(640×480 16.7M Color)下,不同顯示適配卡的每線字節數是不一樣的, 如ARK2000PV 為1920, GD5434及TGUI9440為2048,S3 86C868為2560, 但由于使用VESA編程, 4F01H號功能能準確返回每線字節Line-bytes 值, 并預先算出每條掃描線始址存于addr數組,可提高顯示速度,由于滿屏需900K以上字節,故編程上仍需考慮切換VRAM頁的情況,換頁機制同64K色情形;

        4.有些裝2M VRAM的適配卡, 可在640×480 16.7M色情況下使用32位快速格式,如S3 86C868的112H模式及GD5434的76H模式, 每線字節為2560, 此時解壓縮后按紅綠藍及一零字節順序送視頻緩沖區始址 A000:0000,每一像素4字節,每送一像素到視頻緩沖區,地址偏移量加4,類似特殊情況,例程照此稍作修改便可;

        5.顯示完畢,調用VESA BIOS 4F02H號功能置模式03H,恢復原文本模式。

        六、示范程序
        以上兩種編程實現見所附例程,程序在有ISA/VESA/PCI三種總線插槽的 OctekHippo12型主板、AMD DX4/100 CPU、8M RAM、EMC1024×768、28隔行掃描彩色顯示器、Cirrus GD5434(2M VRAM)顯示卡、Borland C++ 3.1 Small 模式下編譯通過。但執行程序并不依賴所編譯的硬件環境, 曾經在裝有 1M VRAM 的TGUI9440、TGUI9680、ARK2000PV、S3 86C868 等VESA局部總線、PCI局部總線、甚至ISA總線的TVGA8900D(也支持VESA 1.2標準, 1M以下的OEM模式號同TGUI9440)顯示卡的486~586各檔PC機的DOS環境下均獲通過。


        示例程序對Super VGA卡VESA BIOS高、真彩色擴展模式編程具有一般性。對本文未提到的其它高、真彩色顯示卡,只要其支持VESA標準(Version>1.1),不加修改或稍作修改便可使用;對更高分辨率,只要顯示適配卡配2M VRAM, 便可作115H、116H、117H模式的編程, 例程中只要修改highcolor()、truecolor()兩函數中n、m的寬高界值和addr的上界。但更重要的是: 程序運行以前用顯示適配卡所配調整DRAM像素時鐘或調整彩色顯示器掃描頻率的實用程序, 將像素時鐘和掃描頻率調整到該卡現行分辨率所要求的值上, 例如, Cirrus GD5434卡(2M VRAM)要在117H模式下順利仿真顯示16.7M真彩色, 須在DOS下先執行 CLMODE.EXE t640=60 t800=60t1024=60 t1280=0, 程序便可順利顯示高彩色圖像。
        // 24位PCX高、真彩色圖像顯示例程
        #include
        #include
        #include
        #include
        #include
        #include
        #include
        #include
        #include
        unsigned long dataoffset,Line-bytes;
        unsigned long addr;
        unsigned int Curpage,Wingran,Y-res,width,height;
        FILE *fp;
        typedef struct { // PCX圖像文件頭格式
        char manufacturer;
        char version;
        char encoding;
        char bits-perpixel;
        int xmin, ymin;
        int xmax, ymax;
        int hres;
        int vres;
        char palette;
        char reserved;
        char color-planes;
        int bytes-perline;
        int palettetype;
        char filler;
        } PCXHEAD;
        struct mode infoblock {
        unsigned int modeattr;
        unsigned char winaattr;
        unsigned char winbattr;
        unsigned int wingran;
        unsigned int winsize;
        unsigned int winaseg;
        unsigned int winbseg;
        unsigned char *pagefunc;
        unsigned int bytesperscanline;
        unsigned int xres,yres;
        unsigned char charx,chary;
        unsigned char numberofplanes;
        unsigned char bitperpixel;
        unsigned char numberofbanks;
        unsigned char memorymodel;
        unsigned char banksize;


        unsigned char numberofimagepages;
        unsigned char Reserved;
        unsigned char x;
        } modeinfo;
        void SetVesaMode(unsigned int mode);
        void VesaInfo(unsigned int mode);
        void map(void);
        void Selectpage(unsigned int page);
        void highcolor(void);
        void truecolor(void);
        main() // 主函數
        { PCXHEAD header;
        char *filename,c;
        printf("Please enter the 640X480 24bit RGB mode PCX fil
        ename: ");
        gets(filename);
        if((fp=fopen(filename, "rb"))==NULL)
        {
        SetVesaMode(0x03);
        puts("File reading error");
        exit(1);
        }

        fread( (char *) &header, 1, sizeof(PCXHEAD), fp);
        width = header.bytes-perline;
        height = header.ymax - header.ymin + 1;
        printf("Image information: Width=%d, Height=%d",width,h
        eight);
        if ((header.bits-perpixel==8)&&(header.color-planes==3)
        ) {
        printf("
        Type : 24bits RGB true colors");
        printf("1...Emulating display 16M true color image with
        64K high color");
        printf("2...Display of 16M true color image");
        printf("Press select 1 or 2 : ");
        if ((c=getch())=='1') {
        highcolor();
        SetVesaMode(0x03);
        }
        else if (c=='2') {
        truecolor();
        SetVesaMode(0x03);
        }
        else {
        printf("This is not high-color & true-color image !")
        ;
        exit(1);
        }
        }
        fclose(fp);
        return 0;
        }
        // 設置VESA BIOS擴展模式函數
        void SetVesaMode(unsigned int mode)
        { union REGS r;
        unsigned int setmode=1;
        r.x.ax=0x4f02;
        r.x.bx=mode;
        int86(0x10,&r,&r);
        if (r.x.ax!=0x4f)
        setmode=0;
        else VesaInfo(mode);
        Curpage=0xffff;
        return(setmode);
        }
        // 返回VESA編程信息函數
        void VesaInfo(unsigned int mode)
        { union REGS r;


        struct SREGS sr;
        r.x.cx=mode;
        r.x.ax=0x4f01;
        sr.es =FP-SEG(&modeinfo);
        r.x.di=FP-OFF(&modeinfo);
        int86x(0x10,&r,&r,&sr);
        Wingran =modeinfo.wingran;
        Line-bytes=modeinfo.bytesperscanline;
        Y-res
        =modeinfo.yres;
        }
        // 計算掃描線始址函數
        void map(void)
        { register int i,j;
        for(i=0; iaddr =(unsigned long)(i)*Line-bytes;
        }
        // 選擇視頻窗口對準頁函數
        void Selectpage(unsigned int page)
        { union REGS r;
        if (page!=Curpage) {
        r.x.bx=0;
        r.x.dx=page*64L/Wingran;
        r.x.ax=0x4f05;
        int86(0x10,&r,&r);
        Curpage=page;
        }
        }
        // 16位高彩色仿真24位PCX真彩色圖像顯示函數
        void highcolor(void)
        { register int i, j;
        unsigned int red, green, blue;
        unsigned int *word, *wordptr;
        int n, m, k, cnt, total;
        unsigned long segmet;
        unsigned char *pic, *p0,*p1,*p2;
        unsigned char page, picdata;
        SetVesaMode(0x111);
        map();
        Selectpage(0);
        n=min(480,height);
        m=min(640,width);
        word =(unsigned int *)malloc(2*m);
        wordptr=word;
        for (k=0; k<3; k++)
        pic=(unsigned char *)malloc(m);
        p0=pic; p1=pic; p2=pic;
        fseek(fp,0x80L,SEEK-SET);
        for(i=0; ipic=p0; pic=p1; pic=p2;
        word=wordptr;
        for (j=0;j<3;j++) {
        total = 0;
        while(total < m) {
        cnt = 1;
        picdata = fgetc(fp);
        if(0xc0==(0xc0 & picdata)) {
        cnt = 0x3f & picdata;
        picdata = fgetc(fp);
        for (k=0; k*pic++ =picdata;
        }
        else
        *pic++ =picdata;
        total+=cnt;
        }
        }
        pic=p0; pic=p1; pic=p2;
        for (j=0; jred = *pic++ >>3;
        green= *pic++ >>2;
        blue = *pic++ >>3;
        red=red<<11; green=green<<5;
        *word++ =red|green|blue;
        }
        word=wordptr;
        for (j=0;j<2*(m-1);j+=2) {
        segmet=addr+j;
        page=segmet>>16;
        if (segmet <= 65535L) {
        poke(0xa000, addr+j, *word++ );
        }
        else {
        Selectpage(page);
        poke(0xa000, addr+j, *word++ );
        }
        }
        }


        getch();
        free(wordptr); free(pic);
        free(pic) ; free(pic);
        }
        // 24位PCX真彩色圖像全息顯示函數
        void truecolor(void)
        { register int i, j;
        unsigned char *pic, *p0,*p1,*p2;
        unsigned char page, picdata;
        int n,m,k,cnt,total;
        unsigned long segmet;
        SetVesaMode(0x112);
        map();
        Selectpage(0);
        n=min(480,height);
        m=min(640,width);
        for (k=0; k<3; k++)
        pic=(unsigned char *)malloc(m);
        p0=pic; p1=pic; p2=pic;
        fseek(fp,0x80L,SEEK-SET);
        for(i=0; ipic=p0; pic=p1; pic=p2;
        for (j=0;j<3;j++) {
        total = 0;
        while(total < m) {
        cnt = 1;
        picdata = fgetc(fp);
        if(0xc0==(0xc0 & picdata)) {
        cnt = 0x3f & picdata;
        picdata = fgetc(fp);
        for (k=0; k*pic++ =picdata;
        }
        else
        *pic++ =picdata;
        total+=cnt;
        }
        }
        pic=p0; pic=p1; pic=p2;
        for (j=0;j<3*(m-1);j+=3) {
        segmet=addr+j;
        page=segmet>>16;
        if (segmet <= 65535L) {
        for (k=0; k<3; k++)
        pokeb(0xa000, addr+j+k, *pic++);
        }
        else {
        Selectpage(page);
        for (k=0; k<3; k++)
        pokeb(0xa000, addr+j+k, *pic++);
        }
        }
        }
        getch();
        for (k=0; k<3; k++) free(pic);
        }

        參考文獻

        1.張一波.Super VGA與VESA編程指南.北京:海洋出版社,1993.8

        2.張益明.微機圖像文件格式大全(續篇).北京:學苑出版社,1994.7

        【DOS真彩色模式下真彩色圖像顯示技術】相關文章:

        靜態圖像的直接顯示03-06

        DOS下DSP播音的編程03-03

        在 DOS 下使用Windows *.WAV 文件03-03

        利用DVI實現雙屏幕超寬圖像顯示03-18

        DOS界面下通用圖形編輯軟件的設計03-06

        基于圖像的OMR技術的實現03-07

        在DOS實模式下直接存取4GB內存03-19

        開放式創新模式下的技術創新能力研究03-22

        圖像實時傳輸技術在我院中的應用03-18

        国产高潮无套免费视频_久久九九兔免费精品6_99精品热6080YY久久_国产91久久久久久无码

        1. <tt id="5hhch"><source id="5hhch"></source></tt>
          1. <xmp id="5hhch"></xmp>

        2. <xmp id="5hhch"><rt id="5hhch"></rt></xmp>

          <rp id="5hhch"></rp>
              <dfn id="5hhch"></dfn>