基于system verilog的图像处理验证平台(一) bmp文件解析

原创 2018年04月15日 11:18:55

版权所有:转载请注明 https://blog.csdn.net/jayash/article/details/79947314

      基于FPGA的图像处理中,rtl代码的仿真验证一直是重中之重, 之前也在我们的书中《基于FPGA的数字图像处理原理及应用》(电子工业出版社)中提出了基于VC和verilog的仿真验证平台。该验证平台仅能提供简单的图像数据的交互,并且需要VC平台的交互。VC可提供较好的UI功能,但是对于一些中间结果的验证还是比较麻烦。最近刚好学习了system verilog,其面对对象的设计特性很类似于C++,可完整实现更加方便和功能更加全面的testbench平台。

        今天主要介绍bmp文件的读取及解析。bmp文件的格式详解可参考以下链接:

        https://www.cnblogs.com/l2rf/p/5643352.html

        bmp文件解析主要是bmp文件头的解析以及图像数据内容的重定位。bmp文件头主要类型定义如下:

typedef struct{
        u32   biSize;
        u32   biWidth;
        u32   biHeight;
        u16   biPlanes;
        u16   biBitCount;
        u32   biCompression;
        u32   biSizeImage;
        u32   biXPelsPerMeter;
        u32   biYPelsPerMeter;
        u32   biClrUsed;
        u32   biClrImportant;
    } BITMAPINFOHEADER;

    typedef struct {
        u8    rgbBlue;
        u8    rgbGreen;
        u8    rgbRed;
        u8    rgbReserved;
    } RGBQUAD;


    typedef struct {
        BITMAPINFOHEADER    bmiHeader;
        RGBQUAD             bmiColors[1];
    } BITMAPINFO;

    typedef struct  {
        u16    bfType;
        u32    bfSize;
        u16    bfReserved1;
        u16    bfReserved2;
        u32    bfOffBits;
    } BITMAPFILEHEADER;

        bmp文件主要有两个header,包括一个14字节的header BITMAPFILEHEADER,包含了bmp文件头信息,以及 一个40字节的header BITMAPINFOHEADER,包含了bmp文件的图像相关信息。

        解析的主要要点有:

    1 内存存放问题:分辨率不为4的倍数的每一行之后会补零,保证每一行的占用内存是4的倍数;

    2 数据组织问题:bmp的组织原则是首先存放最后一行,接着倒数第二行,以此类推,解析时需还原;

    解析代码如下:(代码为system verilog)

class spk_bmp;
    
    function void trans_16(reg [15:0] _reg,ref u16 dat);
        dat = (_reg[7:0]<<8) + _reg[15:8];
    endfunction
    
    function void trans_32(reg [31:0] _reg,ref u32 dat);
        dat = (_reg[7:0]<<24)+ (_reg[15:8]<<16)+ (_reg[23:16]<<8) + _reg[31:24];
    endfunction
    
    function  int LoadVectorFromBMPFile(string name,ref u8 data[], ref u16 height,ref u16 width,ref u16 flag);
        u32 skip,position;
        u32 dwSize;
	    u32 dReadWidth;
        reg [8*14-1:0] header1;
        reg [8*40-1:0] header2;
        reg [8-1:0]    data_tmp; 
        u32 off = 8*14-1;
        BITMAPFILEHEADER bfh;
        BITMAPINFO bmi;
        
        //判断文件是否存在
        int fp = $fopen(name, "r");
        if(!fp) begin 
            $display("Error: can not open file: %s!",name);
            $stop;
            return -1;
        end 
       
        //读header1
        $fread(header1,fp,0,14); off = 14*8 - 1;
        trans_16(header1[off -: 2*8],bfh.bfType);       off -= 2*8;
        trans_32(header1[off -: 4*8],bfh.bfSize);       off -= 4*8;
        trans_16(header1[off -: 2*8],bfh.bfReserved1);  off -= 2*8;
        trans_16(header1[off -: 2*8],bfh.bfReserved2);  off -= 2*8;
        trans_32(header1[off -: 4*8],bfh.bfOffBits);    off -= 4*8;
        
        if(bfh.bfType != 16'h4d42) begin  
            $display("Error: '%s' is not a bmp file!",name);
            $stop;
            return -1;
        end 
        
        //读header2
        $fread(header2,fp,14,40); off = 40*8 - 1;
        trans_32(header2[off -: 4*8],bmi.bmiHeader.biSize);          off -= 4*8;
        trans_32(header2[off -: 4*8],bmi.bmiHeader.biWidth);         off -= 4*8;
        trans_32(header2[off -: 4*8],bmi.bmiHeader.biHeight);        off -= 4*8;
        trans_16(header2[off -: 2*8],bmi.bmiHeader.biPlanes);        off -= 2*8;
        trans_16(header2[off -: 2*8],bmi.bmiHeader.biBitCount);      off -= 2*8;
        trans_32(header2[off -: 4*8],bmi.bmiHeader.biCompression);   off -= 4*8;
        trans_32(header2[off -: 4*8],bmi.bmiHeader.biSizeImage);     off -= 4*8;
        trans_32(header2[off -: 4*8],bmi.bmiHeader.biXPelsPerMeter); off -= 4*8;
        trans_32(header2[off -: 4*8],bmi.bmiHeader.biYPelsPerMeter); off -= 4*8;
        trans_32(header2[off -: 4*8],bmi.bmiHeader.biClrUsed);       off -= 4*8;
        trans_32(header2[off -: 4*8],bmi.bmiHeader.biClrImportant);  off -= 4*8;
        
        height = bmi.bmiHeader.biHeight;
        width  = bmi.bmiHeader.biWidth;
        flag   = bmi.bmiHeader.biBitCount; 
        
        if(flag == 24) width *= 3; //真彩图
		dwSize     = height * width; 
        dReadWidth = (width+3)/4*4;         
        data       = new[dwSize];
        skip       = dReadWidth - width; 
        position   = dwSize - width;
        off        = bfh.bfOffBits; //第一行图像数据偏移 
        
        $fseek(fp,off,0);
        for(int i = 0;i < height;i++) begin 
            for(int j = 0;j < width;j++) begin
                $fread(data_tmp,fp,off,1); 
                data[position] = data_tmp;
                off++;
                $fseek(fp,off,0);
                position++;
            end 
            position -= 2*width;
            off += skip;            
        end 
        
        $fclose(fp);
        if(flag==24) width /= 3;
    endfunction

endclass : spk_bmp
                

基于CDN平台的DDOS攻击防护

-
  • 1970年01月01日 08:00

Verilog读写文件

在通过编写Verilog代码实现ram功能时,需要自己先计算寄存器的位数和深度再编写代码。而如果需要在编写的ram中预置值的话,就需要使用Verilog语言编写程序读写文件,来将相应的数据赋给寄存器。...
  • hongbin_xu
  • hongbin_xu
  • 2017-04-03 09:50:03
  • 2365

Verilog 如何读取并写入文件

Abstract Verilog雖然為硬體描述語言,亦提供讀取/寫入文字檔的功能。 Introduction 為什麼需要用Verilog讀取/寫入文字檔呢?主要用在寫Testbench,並且...
  • xuexiaokkk
  • xuexiaokkk
  • 2015-12-11 17:57:55
  • 1963

Verilog下的image processing---第一话---读取旋转并写入

为了实现硬件加速而把C code转化为Verilog。 参考的是: http://beiciliang.weebly.com/uploads/2/4/3/1/24316476/verilog.pdf ...
  • mathson
  • mathson
  • 2014-03-25 09:52:58
  • 2562

基于system verilog的图像处理验证平台(一) bmp文件解析

版权所有:转载请注明 https://blog.csdn.net/jayash/article/details/79947314      基于FPGA的图像处理中,rtl代码的仿真验证一直是重中之重...
  • jayash
  • jayash
  • 2018-04-15 11:18:55
  • 71

c语言读取bmp文件完整版

#include #include /* 定义WORD为两个字节的类型 */ typedef unsigned short WORD; /* 定义DWORD为四个字节的类型 */ typedef...
  • weiaipan1314
  • weiaipan1314
  • 2016-06-24 15:43:55
  • 1644

Verilog的信号强度学习

现在在cadence中用NC仿真数字电路的时候,遇到了信号强度的问题,就研究了以下。原来verilog中是可以将多个输出接在一起的,但是要为输出指定信号的强度。 强度值是用来解决数字电路...
  • xuexiaokkk
  • xuexiaokkk
  • 2015-11-11 16:37:56
  • 1270

CBitmap程序中动态加载 本地文件上的BMP图片资源

bool LoadBmpPic(const CString strBmpPath, CBitmap &bmp){ HBITMAP   bitmap; try {  bmp.Detach();  bit...
  • zmq5411
  • zmq5411
  • 2011-03-29 16:18:00
  • 1728

通过写framebuffer显示BMP图片

#include #include #include #include #include #include #include #include #include //14byte文件头typedef ...
  • yuyin86
  • yuyin86
  • 2011-07-05 10:07:07
  • 938

【第二课】读取并显示图像

再次欢迎大家来到这个小巧的指导教程,版本号仅仅比上个单元高一个点。在本单元中,大家将会学到怎样在您的SDL程序、游戏或者是效果展示等实例中载入并显示图像文件。学习过程中,我将带大家几乎逐行通读整个源代...
  • slj_win
  • slj_win
  • 2014-05-22 10:00:01
  • 633
收藏助手
不良信息举报
您举报文章:基于system verilog的图像处理验证平台(一) bmp文件解析
举报原因:
原因补充:

(最多只允许输入30个字)