⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 compressor.vhd

📁 JPEG标准下图象压缩的vhdl实现工程
💻 VHD
📖 第 1 页 / 共 5 页
字号:
            when 2 =>
               result := "001000000000011";
            when 3 =>
               result := "001000000000100";
            when 4 =>
               result := "001000000000101";
            when 5 =>
               result := "001000000000110";
            when 6 =>
               result := "001100000001110";
            when 7 =>
               result := "010000000011110";
            when 8 =>
               result := "010100000111110";
            when 9 =>
               result := "011000001111110";
            when 10 =>
               result := "011100011111110";
            when others => --11
               result := "100000111111110";
         end case;
      else --DC chrominance table
         case Cat is
            when 0 =>
               result := "000100000000000";
            when 1 =>
               result := "000100000000001";
            when 2 =>
               result := "000100000000010";
            when 3 =>
               result := "001000000000110";
            when 4 =>
               result := "001100000001110";
            when 5 =>
               result := "010000000011110";
            when 6 =>
               result := "010100000111110";
            when 7 =>
               result := "011000001111110";
            when 8 =>
               result := "011100011111110";
            when 9 =>
               result := "100000111111110";
            when 10 =>
               result := "100101111111110";
            when others => --11
               result := "101011111111110";
         end case;
      end if;   
      return result;
   end CompressDC;
      
begin
   
   with Save select addr <= addribk when '1', addri when others;
   
   with CompressingInt select addrY <= addrY2 when '1', addrY1 when others;
   with CompressingInt select addrCb <= addrCb2 when '1', addrCb1 when others;
   with CompressingInt select addrCr <= addrCr2 when '1', addrCr1 when others;
   
   with CompressingInt select weY <= weY2 when '1', weY1 when others;
   with CompressingInt select weCb <= weCb2 when '1', weCb1 when others;
   with CompressingInt select weCr <= weCr2 when '1', weCr1 when others;
   
   with CompressingInt select dinY <= dinY2 when '1', dinY1 when others;
   with CompressingInt select dinCb <= dinCb2 when '1', dinCb1 when others;
   with CompressingInt select dinCr <= dinCr2 when '1', dinCr1 when others;
   
   DCT1 : dct2d port map (ND,RDY,RFD,clk,DIND,DOUTD);

   buffer_compY : buffer_comp port map (addrY,clk,dinY,doutY,weY);
   buffer_compCb : buffer_comp_chrom port map (addrCb,clk,dinCb,doutCb,weCb);
   buffer_compCr : buffer_comp_chrom port map (addrCr,clk,dinCr,doutCr,weCr);

   Q_ROM1 : q_rom port map (addrQ,clk,doutQ);
   Huffman_ROM : huff_rom port map (addrH,clk,doutH);
   Tabla_Q1 : tabla_q port map(addrTablaQ,clk,doutTablaQ);

   
   
   
   RGB2YCbCr : process(reset, clk)
      --It applies the transformation from RGB to YCBCr and pass it to the JPEG process
      -- but what we are going to save in the buffers will be the pixels of the components with
      -- the JPEG level shift already applied, so that the transformation's last addition: [0;128;128] will become -[128;0;0]
      variable Baton : integer range 0 to 3 := 0; --indicates the current state of the FSM
      variable Red1 : std_logic_vector(17 downto 0);
      variable Red2 : std_logic_vector(17 downto 0);
      variable Red3 : std_logic_vector(17 downto 0);
      variable Green1 : std_logic_vector(17 downto 0);
      variable Green2 : std_logic_vector(17 downto 0);
      variable Green3 : std_logic_vector(17 downto 0);
      variable Blue1 : std_logic_vector(17 downto 0);
      variable Blue2 : std_logic_vector(17 downto 0);
      variable Blue3 : std_logic_vector(17 downto 0);
      
      variable Cb, Cr : std_logic_vector(10 downto 0);
   begin
      if (reset = '1') then
         Compressing <= '0';
         addrY1 <= (others => '0');
         addrCb1 <= (others => '0');
         addrCr1 <= (others => '0');
         weY1 <= '0';
         weCb1 <= '0';
         weCr1 <= '0';
         dinCb1 <= (others => '0');
         dinCr1 <= (others => '0');
         dinY1 <= (others => '0');
         LineToCompress <= "0000";
         LineAbsToCompress <= (others => '0');
         ColumnToCompress <= (others => '0');
         Baton := 0;
         Cb := (others => '0');
         Cr := (others => '0');
         ProcessingRGB <= '0';
         MakeDCT <= '0';
         Red1 := (others => '0');
         Red2 := (others => '0');
         Red3 := (others => '0');
         Green1 := (others => '0');
         Green2 := (others => '0');
         Green3 := (others => '0');
         Blue1 := (others => '0');
         Blue2 := (others => '0');
         Blue3 := (others => '0');
      elsif (clk = '1' and clk'event) then
         if CompressImage = '1' then
            Compressing <= '1';
            addrY1 <= (others => '0');
            addrCb1 <= (others => '0');
            addrCr1 <= (others => '0');
            weY1 <= '0';
            weCb1 <= '0';
            weCr1 <= '0';
            
            LineToCompress <= "0000";
            LineAbsToCompress <= (others => '0');
            ColumnToCompress <= (others => '0');
            Baton := 0;
            ProcessingRGB <= '0';
         end if;

         
         if (ProcessRGB = '1') then
            ProcessingRGB <= '1'; --while this one is high, there won't be another ProcessRGB='1'
            Baton := 1;
         end if;

         addrY1 <= Mult_Columns(LineToCompress) + ColumnToCompress;
         addrCb1 <= Mult_Half_Columns(LineToCompress(3 downto 1)) + (ColumnToCompress(9 downto 1)); --for the subsampling
         addrCr1 <= Mult_Half_Columns(LineToCompress(3 downto 1)) + (ColumnToCompress(9 downto 1));
         --we pre-read the saved data, so as to average the chroma components Cb and Cr
         --to be able to do a proper subsampling 2x2 1x1 1x1
         
         case Baton is
            when 0 =>
               weY1 <= '0';
               weCb1 <= '0';
               weCr1 <= '0';
               MakeDCT <= '0';

            when 1 =>                                    
               --we apply only the transformation RGB to YCbCr
               Red1 := Multiplier(Red, "0010011001"); --153
               Red2 := Multiplier(Red, "0010101101"); --173
               Red3 := "0000000000" & Red; --1
               Green1 := Multiplier(Green, "1001011001"); --601
               Green2 := Multiplier(Green, "0101010011"); --339
               Green3 := Multiplier(Green, "0110101101"); --429
               Blue1 := Multiplier(Blue, "0001110101"); --117
               Blue2 := "0000000000" & Blue; --1
               Blue3 := Multiplier(Blue, "0001010011"); --83
               --the largest obtainable result would be 255*601=153255 (100101011010100111)
               Baton := 2;
               
               MakeDCT <= '0';
            when 2 =>
               --dinY1 <= "111110000000"; --for debugging, to make Y zero, so that in the resulting image the Blue channel will be Cb and the Red one will be Cr
               dinY1 <= "0000" & (Red1(16 downto 9) + Green1(17 downto 10) + Blue1(17 downto 10) - "10000000");-- + Red1(8) + Green1(9) + Blue1(9)); --Red1/512+Green1/1024+Blue1/1024 and with -128 for the level shift
               if Mono = '1' then
                  Cb := (others => '0');
                  Cr := (others => '0');
               else
                  Cb := "000" & (Blue2(8 downto 1) - Red2(17 downto 10) - Green2(17 downto 10)); -- + Blue2(0) - Red2(9) - Green2(9)); --Red & Green between 1024 and Blue between 2
                  Cr := "000" & (Red3(8 downto 1) - Green3(17 downto 10) - Blue3(17 downto 10)); -- + Red3(0) - Green3(9) - Blue3(9)); --between 1024 all but Red
                  --debug: the bits added/substracted at the end are the nearest integer rounding
               end if;   
               
               --Subsampling: average groups of 4 pixels in blocks of 2x2
               if LineAbsToCompress(0) = '0' and ColumnToCompress(0) = '0' then --element (0,0)
                  --dinCb1 <= "0000" & Cb(7 downto 0);
                  --dinCr1 <= "0000" & Cr(7 downto 0);
                  dinCb1 <= "0000" & Cb(7 downto 0);
                  dinCr1 <= "0000" & Cr(7 downto 0);
               elsif LineAbsToCompress(0) = '0' and ColumnToCompress(0) = '1' then --element (0,1)
                  Cb := (Cb(7) & Cb(7) & Cb(7) & Cb(7 downto 0)) + (doutCb(7) & doutCb(7 downto 0));
                  Cr := (Cr(7) & Cr(7) & Cr(7) & Cr(7 downto 0)) + (doutCr(7) & doutCr(7 downto 0));
                  dinCb1 <= "000" & Cb(8 downto 0);
                  dinCr1 <= "000" & Cr(8 downto 0);   
               elsif LineAbsToCompress(0) = '1' and ColumnToCompress(0) = '0' then --element (1,0)
                  Cb := (Cb(7) & Cb(7) & Cb(7) & Cb(7 downto 0)) + (doutCb(8) & doutCb(8 downto 0));
                  Cr := (Cr(7) & Cr(7) & Cr(7) & Cr(7 downto 0)) + (doutCr(8) & doutCr(8 downto 0));
                  dinCb1 <= "00" & Cb(9 downto 0);
                  dinCr1 <= "00" & Cr(9 downto 0);   
               else --element (1,1) before, we have added directly, now we add and write the average of the 4 pixels, so as to not lose precission
                  Cb := (Cb(7) & Cb(7) & Cb(7) & Cb(7 downto 0)) + (doutCb(9) & doutCb(9 downto 0));
                  Cr := (Cr(7) & Cr(7) & Cr(7) & Cr(7 downto 0)) + (doutCr(9) & doutCr(9 downto 0));
                  dinCb1 <= "0000" & Cb(9 downto 2);
                  dinCr1 <= "0000" & Cr(9 downto 2);

                  --next lines are for debugging purposes (instead of the last if,elsifs and else to write just
                  --one chrominance value for Cb and Cr instead of averaging)
                  --Cb := (Cb(7) & Cb(7) & Cb(7) & Cb(7 downto 2)) + (doutCb(7) & doutCb(7 downto 0));
                  --Cr := (Cr(7) & Cr(7) & Cr(7) & Cr(7 downto 2)) + (doutCr(7) & doutCr(7 downto 0));
                  --dinCb1 <= "0000" & Cb(7 downto 0);
                  --dinCr1 <= "0000" & Cr(7 downto 0);
                  --weCb1 <= '1';
                  --weCr1 <= '1';               
               --else
                  --weCb1 <= '0';
                  --weCr1 <= '0';               
               end if;   
                  
               weY1 <= '1';
               weCb1 <= '1';
               weCr1 <= '1';

               if (LineToCompress(2 downto 0) = "111") then
                  if (ColumnToCompress(2 downto 0) = "111") then --we've just written pixel 64 of the block [of 64 pixels]
                     MakeDCT <= '1';                                                             
                  else
                     MakeDCT <= '0';
                  end if;   
               else                  
                  MakeDCT <= '0';
               end if;
               
               if (ColumnToCompress = ImgColumns) then
                  LineToCompress <= LineToCompress + 1;
                  LineAbsToCompress <= LineAbsToCompress + 1;
                  ColumnToCompress <= (others => '0');
               else
                  ColumnToCompress <= ColumnToCompress + 1;
               end if;               
               
               Baton := 3;
            when 3 => --with this dummy cycle we give time to CompressingInt to rise, if it must, and make the following "if" work fine
               weY1 <= '0';
               weCb1 <= '0';
               weCr1 <= '0';
               MakeDCT <= '0';
               Baton := 0;
         end case;
         --MakeDCT is rised in cycle 0, in cycle 1 it is read by the process JPEG which then rises CompressingInt
         --and in cycle 2 this process reads CompressingInt='1' so that in that intermediate cycle 1 is when
         --the case "when 3 =>" gets executed and the following "if", in which MakeDCT is 1 and CompressingInt is 0
         --but it is going to be inverted.
         if (Baton = 0 and MakeDCT = '0' and CompressingInt = '0') then --it is fine!
            if (LineAbsToCompress > ImgLines) then
               Compressing <= '0'; --Compression has ended, image ready
               LineAbsToCompress <= (others => '0'); --absolutely incredible, without this line it will only work for the
                              --first image (it took me much time to debug this one, folks)
            end if;   
            ProcessingRGB <= '0';
         end if;   
         

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -