📄 compressor.vhd
字号:
subtype Byte is ByteT; --well, maybe I oversubtyped it, hehe type ByteFileType is file of Byte; file outfile : ByteFileType open write_mode is "image.jpg"; variable Pixel : Byte; variable bufer: LINE; variable Header : std_logic_vector(4855 downto 0) := X"FFD8FFE000104A46494600010200000100010000FFC00011080020004003012200021101031101FFDB008400100B0C0E0C0A100E0D0E1211101318281A181616183123251D283A333D3C3933383740485C4E404457453738506D51575F626768673E4D71797064785C656763011112121815182F1A1A2F634238426363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363FFC401A20000010501010101010100000000000000000102030405060708090A0B100002010303020403050504040000017D01020300041105122131410613516107227114328191A1082342B1C11552D1F02433627282090A161718191A25262728292A3435363738393A434445464748494A535455565758595A636465666768696A737475767778797A838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE1E2E3E4E5E6E7E8E9EAF1F2F3F4F5F6F7F8F9FA0100030101010101010101010000000000000102030405060708090A0B1100020102040403040705040400010277000102031104052131061241510761711322328108144291A1B1C109233352F0156272D10A162434E125F11718191A262728292A35363738393A434445464748494A535455565758595A636465666768696A737475767778797A82838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE2E3E4E5E6E7E8E9EAF2F3F4F5F6F7F8F9FAFFDA000C03010002110311003F00"; --pragma translate_on begin if (reset = '1') then CompressingInt <= '0'; Linea := (others => '0'); Columna := (others => '0'); Bloque := "00"; StepV <= 0; weY2 <= '0'; weCb2 <= '0'; weCr2 <= '0'; Base := (others => '0'); BaseH := (others => '0'); BaseQ := (others => '0'); DCTQ := (others => '0'); DIND <= (others => '0'); ND <= '0'; --Huffmanear <= '0'; PrevDC := (others => '0'); Coeficiente := 0; HuffmanWord := (others => '0'); HuffmanWordPos := 22; --first free LSB (HuffmanWord's MSB) Elemento := "00"; IniDC := '1'; GetPrevDC := '1'; FirstDC := '1'; Save <= '0'; addri <= "0000000000101100"; --first Table addribk <= "0000001001011110"; --pointer to last Header byte addrH <= (others => '0'); addrQ <= (others => '0'); addrCb2 <= (others => '0'); addrCr2 <= (others => '0'); addrY2 <= (others => '0'); din <= (others => '0'); we <= '0'; dinY2 <= (others => '0'); dinCr2 <= (others => '0'); dinCb2 <= (others => '0'); Done <= '0'; Cat := 0; ZRL := 0; Coef := (others => '0'); ColBk := (others => '0'); LinBk := (others => '0'); Sign := '0'; ZeroRun := 0; Primera := '0'; LumaBlock := '0'; NDe <= '0'; HeaderFinal := '0'; DatoHeader := 0; VarTamImg := (others => '0'); WriteAdditionalBits <= '0'; TempCompDC := (others => '0'); WriteZRL := '0'; LastBlockDCY := (others => '0'); LastBlockDCCb := (others => '0'); LastBlockDCCr := (others => '0'); AddVal := (others => '0'); QDC := (others => '0'); WriteTables <= '0'; TableData <= (others => '0'); Table <= '0'; addrTablaQ <= (others => '0'); ZRLing <= '0'; RFDInt <= '0'; RFDIntData <= (others => '0'); elsif (clk = '1' and clk'event) then if CompressImage = '1' then FirstDC := '1'; IniDC := '1'; HeaderFinal := '0'; GetPrevDC := '1'; PrevDC := (others => '0'); --initialized to zero at the beginning of the image HuffmanWord := (others => '0'); HuffmanWordPos := 22; Save <= '0'; DatoHeader := 0; WriteAdditionalBits <= '0'; HeaderFinal := '0'; WriteTables <= '1'; TableData <= (others => '0'); Table <= '0'; addribk <= "0000001001011110"; --pointer to the Header's last byte addri <= "0000000000101100"; --first Table case Compression is when "00" => --low quality BaseQ := "100000000"; when "01" => --medium quality BaseQ := "010000000"; when others => --10 high quality BaseQ := "000000000"; end case; addrTablaQ <= BaseQ; --ready first data CompressingInt <= '0'; Bloque := "00"; StepV <= 0; weY2 <= '0'; weCb2 <= '0'; weCr2 <= '0'; Base := (others => '0'); BaseH := (others => '0'); ND <= '0'; Coeficiente := 0; we <= '0'; Done <= '0'; ZRLing <= '0'; RFDInt <= '0'; RFDIntData <= (others => '0'); --pragma translate_off Columna := ('0' & ImgLines) + 1; for i in 606 downto 563 loop case i is when (606-25) => --MSByte of size Y Pixel := ByteT'val(conv_integer("0000000" & Columna(8))); when (606-26) => --LSByte of size Y Pixel := ByteT'val(conv_integer(Columna(7 downto 0))); Columna := ImgColumns + 1; when (606-27) => --MSByte of size X Pixel := ByteT'val(conv_integer("000000" & Columna(9 downto 8))); when (606-28) => --LSByte of size X Pixel := ByteT'val(conv_integer(Columna(7 downto 0))); when others => Pixel := ByteT'val(conv_integer(Header(8*i+7 downto 8*i))); end case; write(outfile, Pixel); end loop; --pragma translate_on end if; we <= '0'; --after the ones that rise it if WriteTables = '1' then --write in memory the quantization tables for the selected compression level if Table = '0' then --the start of Table Q of value "00h" is in position 2Bh (43=101011) addri <= "0000000000101100" + ('0' & TableData); else--the start of Table Q of value "01h" is in position 6Ch (108=1101100) addri <= "0000000001101101" + ('0' & TableData); end if; din <= doutTablaQ; addrTablaQ <= addrTablaQ + 1; if addrTablaQ /= BaseQ then --first coefficient, not written because we'll have it also in next cycle --until second coefficient is loaded we <= '1'; TableData <= TableData + 1; --pragma translate_off Pixel := ByteT'val(conv_integer(doutTablaQ)); write(outfile, Pixel); --pragma translate_on end if; if TableData = "111111" then if Table = '1' then --we are over --pragma translate_off for i in 433 downto 0 loop Pixel := ByteT'val(conv_integer(Header(8*i+7 downto 8*i))); write(outfile, Pixel); end loop; --pragma translate_on WriteTables <= '0'; addrTablaQ <= (others => '0'); --so that it doesn't stay in a non-existent address else Table <= '1'; --pragma translate_off Pixel := ByteT'val(1); --points to the start of Table 01 write(outfile, Pixel); --pragma translate_on end if; end if; end if; if (MakeDCT = '1' or CompressingInt = '1') then --MakeDCT lasts only one cycle, but CompressingInt is high the following ones if MakeDCT = '1' then HeaderFinal := '0'; --write the image size, now that we know it, in the header as at the least we must do --4 DCTs in an image, there won't be any problem if image size writing is done in four steps --or if it is repeated throughout the image's processing case DatoHeader is when 0 => --MSByte of ImgLines+1 addri <= "0000000000011001"; --position 0 of the two bytes of size Y (lines) we <= '1'; VarTamImg := ("00" & ImgLines) + 1; din <= "000000" & VarTamImg(9 downto 8); DatoHeader := 1; when 1 => --LSByte of ImgLines+1 addri <= "0000000000011010"; we <= '1'; din <= VarTamImg(7 downto 0); DatoHeader := 2; when 2 => --MSByte of ImgColumns+1 addri <= "0000000000011011"; --position 0 of the two bytes of size X (columns) we <= '1'; VarTamImg := ('0' & ImgColumns) + 1; din <= "00000" & VarTamImg(10 downto 8); DatoHeader := 3; when 3 => --LSByte of ImgColumns+1 addri <= "0000000000011100"; we <= '1'; din <= VarTamImg(7 downto 0); DatoHeader := 4; when 4 to 7 => --it's been already written, don't do anything(we put 8 DatoHeader because in the last --block when we pass to the next image, ImgLines is zero and it is wrongly written) we <= '0'; if DatoHeader = 7 then DatoHeader := 0; else DatoHeader := DatoHeader + 1; end if; end case; CompressingInt <= '1'; if ColumnToCompress = "0000000000" then --we've changed line, careful --because we have to process the last block of the previous line Linea := (not LineToCompress(3)) & "000"; Columna := ImgColumns(9 downto 3) & "000"; else Linea := LineToCompress(3) & "000"; Columna := (ColumnToCompress(9 downto 3) - 1) & "000"; end if; Bloque := ColumnToCompress(1 downto 0); StepV <= 0; weY2 <= '0'; weCb2 <= '0'; weCr2 <= '0'; Coeficiente := 0; Save <= '0'; IniDC := '1'; GetPrevDC := '1'; WriteAdditionalBits <= '0'; else we <= '0'; LumaBlock := Bloque(1) nor Bloque(0); --it is 1 if we are dealing with luminance component --It is necessary that Base be here so that it changes when Bloque changes in the "if" of Done in the last image's block if Bloque = "00" then --Q Coefficients of Table 0 (luminance) BaseH := (others => '0'); --address 0 of Huffman Luminance Table case Compression is when "00" => --Low Quality Base := "100000000"; when "01" => --Medium Quality Base := "010000000"; when others => --10 High Quality Base := "000000000"; end case; else --Q Coefficients of Table 1 (chroma) BaseH := "010110000"; --address 0 of Huffman Chrominance Table case Compression is when "00" => --Low Quality Base := "101000000"; when "01" => --Medium Quality Base := "011000000"; when others => --10 High Quality Base := "001000000"; end case; end if; case StepV is when 0 => --with the first data to let addrXX2 load and have the data in memory weY2 <= '0'; weCb2 <= '0'; weCr2 <= '0'; if CompressingInt = '1' and Done = '0' then --Done=0 cause in case it is a Y block (but not the fourth (the last)) coming from StepV=3
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -