산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Industrial programming >> VHDL

TEXTIO를 사용하여 BMP 파일 비트맵 이미지 읽기

이미지 파일을 비트맵 형식으로 변환하면 VHDL을 사용하여 그림을 읽는 가장 쉬운 방법이 됩니다. BMP 래스터 그래픽 이미지 파일 형식에 대한 지원은 Microsoft Windows 운영 체제에 내장되어 있습니다. 따라서 BMP는 VHDL 테스트벤치에서 사용할 사진을 저장하는 데 적합한 이미지 형식입니다.

이 기사에서는 BMP와 같은 바이너리 이미지 파일을 읽고 시뮬레이터의 동적 메모리에 데이터를 저장하는 방법을 배웁니다. 이미지를 그레이스케일로 변환하기 위해 예제 이미지 처리 모듈을 사용할 것입니다. 이것은 테스트 중인 장치(DUT)가 될 것입니다. 마지막으로 DUT의 출력을 원본과 시각적으로 비교할 수 있는 새 이미지에 씁니다.

이 블로그 게시물은 VHDL에서 TEXTIO 라이브러리를 사용하는 방법에 대한 시리즈의 일부입니다. 여기에서 다른 기사를 읽으십시오:

TEXTIO를 사용하여 파일에서 RAM을 초기화하는 방법

TEXTIO를 사용하여 테스트벤치에서 읽은 자극 파일

비트맵이 VHDL에 가장 적합한 형식인 이유

인터넷에서 가장 일반적인 이미지 파일 형식은 JPEG와 PNG입니다. 둘 다 압축을 사용하며 JPEG는 손실이 있고 PNG는 손실이 없습니다. 대부분의 형식은 이미지의 저장 크기를 크게 줄일 수 있는 압축 형식을 제공합니다. 일반적인 사용에는 괜찮지만 VHDL 테스트벤치에서 읽기에는 적합하지 않습니다.

소프트웨어나 하드웨어에서 이미지를 처리할 수 있으려면 응용 프로그램 내에서 원시 픽셀 데이터에 액세스할 수 있어야 합니다. 색상 및 휘도 데이터를 바이트 행렬에 저장하려고 합니다. 이를 비트맵 또는 래스터 그래픽이라고 합니다.

Photoshop 또는 GIMP와 같은 잘 알려진 이미지 편집기는 대부분 래스터 기반입니다. 다양한 이미지 형식을 열 수 있지만 모두 편집기에서 내부적으로 래스터 그래픽으로 변환됩니다.

VHDL에서도 이 작업을 수행할 수 있지만 압축된 이미지를 디코딩하기 위한 기성 솔루션이 없기 때문에 상당한 코딩 노력이 필요합니다. 더 나은 솔루션은 테스트 입력 이미지를 수동으로 BMP와 같은 비트맵 형식으로 변환하거나 테스트벤치를 시작하는 스크립트에 통합하여 변환하는 것입니다.

BMP 이미지 파일 형식

BMP 파일 형식은 Wikipedia에 잘 설명되어 있습니다. 이 형식에는 다양한 변형이 있지만 훨씬 더 쉽게 만들 수 있는 몇 가지 특정 설정에 동의할 것입니다. 입력 이미지를 생성하기 위해 Windows와 함께 사전 설치된 Microsoft 그림판에서 이미지를 엽니다. 그런 다음 파일→다른 이름으로 저장을 클릭합니다. , 파일 형식:24비트 비트맵(*bmp; *.dib)을 선택합니다. . .bmp 접미사로 끝나는 파일 이름을 지정하고 저장을 클릭합니다.

파일이 이와 같이 생성되었는지 확인하면 헤더가 항상 Wikipedia 페이지에 언급된 픽셀 형식 RGB24를 사용하는 54바이트 길이의 BITMAPINFOHEADER 변형이라고 가정할 수 있습니다. 또한 헤더 내에서 선택된 몇 개의 필드에만 관심을 둘 것입니다. 아래 표는 우리가 읽을 헤더 필드를 보여줍니다.

오프셋(12월) 사이즈(B) 예상(16진수) 설명
0 2 "BM"(42 4D) ID 필드
10 4 54 (36 00 00 00) 픽셀 배열 오프셋
14 4 40 (28 00 00 00) 헤더 크기
18 4 값 읽기 픽셀 단위의 이미지 너비
22 4 값 읽기 픽셀 단위의 이미지 높이
26 1 1 (01) 색상 평면의 수
28 1 24 (18) 픽셀당 비트 수

녹색으로 표시된 값은 다른 헤더 필드에서 예상되는 값을 알고 있기 때문에 실제로 살펴봐야 하는 유일한 값입니다. 매번 미리 정의된 고정 치수의 이미지만 사용하기로 동의했다면 전체 헤더를 건너뛰고 BMP 파일 내의 바이트 오프셋 번호 54에서 읽기를 시작할 수 있습니다. 여기에서 픽셀 데이터를 찾을 수 있습니다.

그럼에도 불구하고 다른 나열된 값이 예상대로인지 확인할 것입니다. 이미 헤더를 읽고 있기 때문에 어렵지 않습니다. 또한 귀하 또는 귀하의 동료 중 한 명이 향후 언제든지 테스트벤치에 잘못된 인코딩 이미지를 제공할 경우 사용자 오류에 대한 보호 기능을 제공합니다.

테스트 케이스

이 블로그 게시물은 VHDL 테스트벤치의 파일에서 이미지를 읽는 방법에 관한 것이지만 완성도를 위해 예제 DUT를 포함했습니다. 이미지를 읽을 때 DUT를 통해 픽셀 데이터를 스트리밍합니다. 마지막으로 좋아하는 사진 뷰어에서 검사할 수 있는 다른 출력 BMP 파일에 결과를 기록합니다.

entity grayscale is
  port (
    -- RGB input
    r_in : in std_logic_vector(7 downto 0);
    g_in : in std_logic_vector(7 downto 0);
    b_in : in std_logic_vector(7 downto 0);

    -- RGB output
    r_out : out std_logic_vector(7 downto 0);
    g_out : out std_logic_vector(7 downto 0);
    b_out : out std_logic_vector(7 downto 0)
  );
end grayscale; 

위의 코드는 DUT의 엔티티를 보여줍니다. 그레이스케일 모듈은 한 픽셀에 대한 24비트 RGB 데이터를 입력으로 받아 출력에 표시되는 그레이스케일 표현으로 변환합니다. 출력 픽셀은 여전히 ​​RGB 색상 공간 내에서 회색 음영을 나타내며 BMP를 다른 형식인 회색조 BMP로 변환하지 않습니다.

모듈은 순전히 조합형이며 클럭 또는 리셋 입력이 없습니다. 입력에 무언가가 할당되면 결과가 즉시 출력에 나타납니다. 단순성을 위해 그레이스케일로 변환할 때 ITU-R BT.2100 RGB에서 루마 코딩 시스템에 따른 루마(밝기) 값의 고정 소수점 근사값을 사용합니다.

아래 양식을 사용하여 회색조 모듈 및 전체 프로젝트에 대한 코드를 다운로드할 수 있습니다.

아래에서 보고 있는 Boeing 747의 사진이 입력 이미지의 예입니다. 즉, 이 블로그 게시물에 포함된 실제 BMP 이미지가 아니므로 불가능합니다. 테스트벤치에서 읽을 BMP 이미지의 JPEG 표현입니다. 위 양식에 이메일 주소를 남겨주시면 원본 BMP 이미지를 요청할 수 있으며 받은편지함으로 바로 받아보실 수 있습니다.

테스트 이미지의 크기는 1000 x 1000픽셀입니다. 그러나 이 기사에 제공된 코드는 BITMAPINFOHEADER 24비트 BMP 형식인 한 모든 이미지 크기에서 작동해야 합니다. 그러나 대부분의 VHDL 시뮬레이터에서 파일 액세스가 느리기 때문에 큰 이미지를 읽는 것은 시뮬레이션 시간이 많이 걸립니다. 이 이미지는 2930kB이며 ModelSim에서 로드하는 데 몇 초가 걸립니다.

TEXTIO 라이브러리 가져오기

VHDL에서 파일을 읽거나 쓰려면 TEXTIO 라이브러리를 가져와야 합니다. VHDL 파일 상단에 아래 목록의 행을 포함해야 합니다. finish도 가져와야 합니다. 모든 테스트가 완료되면 시뮬레이션을 중지하는 표준 패키지의 키워드입니다.

use std.textio.all;
use std.env.finish;

위의 문장은 VHDL-2008 이상을 사용해야 합니다.

사용자 정의 유형 선언

테스트벤치의 선언적 영역이 시작될 때 몇 가지 사용자 정의 유형을 선언할 것입니다. 픽셀 데이터를 저장하기 위한 데이터 구조의 형식은 DUT가 예상하는 입력의 종류에 따라 다릅니다. 회색조 모듈은 각각 빨강, 녹색 및 파랑 색상 구성 요소 중 하나를 나타내는 3바이트를 예상합니다. 한 번에 하나의 픽셀에서 작동하기 때문에 원하는 대로 픽셀 집합을 자유롭게 저장할 수 있습니다.

아래 코드에서 볼 수 있듯이 먼저 header_type을 선언합니다. 모든 헤더 데이터를 저장하는 데 사용할 배열입니다. 헤더 내의 일부 필드를 검사하지만 테스트벤치 끝에서 처리된 이미지 데이터를 새 파일에 쓸 것이기 때문에 저장해야 합니다. 그런 다음 출력 이미지에 원본 헤더를 포함해야 합니다.

type header_type  is array (0 to 53) of character;

type pixel_type is record
  red : std_logic_vector(7 downto 0);
  green : std_logic_vector(7 downto 0);
  blue : std_logic_vector(7 downto 0);
end record;

type row_type is array (integer range <>) of pixel_type;
type row_pointer is access row_type;
type image_type is array (integer range <>) of row_pointer;
type image_pointer is access image_type;

두 번째 명령문은 pixel_type라는 레코드를 선언합니다. . 이 사용자 정의 유형은 한 픽셀에 대한 RGB 데이터의 컨테이너 역할을 합니다.

마지막으로 모든 픽셀을 저장하기 위한 동적 데이터 구조가 선언됩니다. row_type 동안 pixel_type의 제약 없는 배열입니다. , row_pointer VHDL 포인터에 대한 액세스 유형입니다. 마찬가지로, 우리는 제약이 없는 image_type을 구성합니다. 픽셀의 모든 행을 저장할 배열입니다.

따라서 image_pointer type은 동적으로 할당된 메모리의 전체 이미지에 대한 핸들로 작동합니다.

DUT 인스턴스화

선언적 영역의 끝에서 아래와 같이 DUT에 대한 인터페이스 신호를 선언합니다. 입력 신호에는 _in이 접미사로 붙습니다. _out가 있는 출력 신호 . 이를 통해 코드와 파형에서 쉽게 식별할 수 있습니다. DUT는 포트 맵을 통해 할당된 신호로 아키텍처 시작 시 인스턴스화됩니다.

signal r_in : std_logic_vector(7 downto 0);
signal g_in : std_logic_vector(7 downto 0);
signal b_in : std_logic_vector(7 downto 0);
signal r_out : std_logic_vector(7 downto 0);
signal g_out : std_logic_vector(7 downto 0);
signal b_out : std_logic_vector(7 downto 0);

begin

DUT :entity work.grayscale(rtl)
port map (
  r_in => r_in,
  g_in => g_in,
  b_in => b_in,
  r_out => r_out,
  g_out => g_out,
  b_out => b_out
);

프로세스 변수 및 파일 핸들

모든 파일 읽기 및 쓰기를 포함하는 단일 테스트벤치 프로세스를 생성합니다. 프로세스의 선언적 영역은 아래와 같습니다. 새로운 char_file을 선언하는 것으로 시작합니다. type 입력 이미지 파일에서 읽고자 하는 데이터 유형을 정의합니다. BMP 파일은 이진 인코딩됩니다. 따라서 우리는 바이트, character에서 작업하고 싶습니다. VHDL을 입력합니다. 다음 두 줄에서는 유형을 사용하여 입력 및 출력 파일을 엽니다.

process
  type char_file is file of character;
  file bmp_file : char_file open read_mode is "boeing.bmp";
  file out_file : char_file open write_mode is "out.bmp";
  variable header : header_type;
  variable image_width : integer;
  variable image_height : integer;
  variable row : row_pointer;
  variable image : image_pointer;
  variable padding : integer;
  variable char : character;
begin

다음으로 헤더 데이터를 포함할 변수와 이미지의 너비와 높이를 유지하기 위한 두 개의 정수 변수를 선언합니다. 그런 다음 row를 선언합니다. 포인터 및 image 바늘. 후자는 파일에서 읽은 후 전체 이미지에 대한 핸들이 됩니다.

마지막으로 두 개의 편의 변수를 선언합니다. padding integer 유형 및 char character 유형 . 파일에서 읽은 값을 임시로 저장하는 데 사용합니다.

BMP 헤더 읽기

프로세스 본문의 시작 부분에서 BMP 파일의 전체 헤더를 header으로 읽습니다. 아래 코드와 같이 변수. 헤더의 길이는 54바이트이지만 하드 코딩된 값을 사용하는 대신 header_type'range을 참조하여 반복할 범위를 얻습니다. 기인하다. 가능한 한 적은 위치에 정의된 상수 값을 유지할 수 있을 때 항상 속성을 사용해야 합니다.

  for i in header_type'range loop
    read(bmp_file, header(i));
  end loop;

그런 다음 일부 헤더 필드가 예상대로인지 확인하는 몇 가지 assert 문을 따릅니다. 이것은 우리가 읽은 값을 아무 것도 사용하지 않기 때문에 사용자 오류에 대한 안전 장치이며 예상대로인지 확인합니다. 예상 값은 기사 앞부분에 나와 있는 이 표에 나열된 값입니다.

아래 코드는 각각 report가 있는 assert 문을 보여줍니다. 오류를 설명하는 문 및 severity failure 주장된 표현식이 false인 경우 시뮬레이션을 중지하는 명령문 . 최소한 ModelSim의 기본 설정에서는 오류 메시지를 출력하고 시뮬레이션을 계속하기 때문에 심각도를 높여야 합니다.

  -- Check ID field
  assert header(0) = 'B' and header(1) = 'M'
    report "First two bytes are not ""BM"". This is not a BMP file"
    severity failure;

  -- Check that the pixel array offset is as expected
  assert character'pos(header(10)) = 54 and
    character'pos(header(11)) = 0 and
    character'pos(header(12)) = 0 and
    character'pos(header(13)) = 0
    report "Pixel array offset in header is not 54 bytes"
    severity failure;

  -- Check that DIB header size is 40 bytes,
  -- meaning that the BMP is of type BITMAPINFOHEADER
  assert character'pos(header(14)) = 40 and
    character'pos(header(15)) = 0 and
    character'pos(header(16)) = 0 and
    character'pos(header(17)) = 0
    report "DIB headers size is not 40 bytes, is this a Windows BMP?"
    severity failure;

  -- Check that the number of color planes is 1
  assert character'pos(header(26)) = 1 and
    character'pos(header(27)) = 0
    report "Color planes is not 1" severity failure;

  -- Check that the number of bits per pixel is 24
  assert character'pos(header(28)) = 24 and
    character'pos(header(29)) = 0
    report "Bits per pixel is not 24" severity failure;

그런 다음 헤더에서 이미지 너비 및 높이 필드를 읽습니다. 이것들은 우리가 실제로 사용할 유일한 두 가지 값입니다. 따라서 image_width에 할당합니다. 및 image_height 변수. 아래 코드에서 볼 수 있듯이 4바이트 헤더 필드를 적절한 정수 값으로 변환하려면 후속 바이트에 두 값의 가중 거듭제곱을 곱해야 합니다.

  -- Read image width
  image_width := character'pos(header(18)) +
    character'pos(header(19)) * 2**8 +
    character'pos(header(20)) * 2**16 +
    character'pos(header(21)) * 2**24;

  -- Read image height
  image_height := character'pos(header(22)) +
    character'pos(header(23)) * 2**8 +
    character'pos(header(24)) * 2**16 +
    character'pos(header(25)) * 2**24;

  report "image_width: " & integer'image(image_width) &
    ", image_height: " & integer'image(image_height);

마지막으로 report을 사용하여 시뮬레이터 콘솔에 읽기 높이와 너비를 인쇄합니다. 성명서.

픽셀 데이터 읽기

픽셀 데이터를 읽기 시작하기 전에 각 행에 패딩이 몇 바이트인지 알아야 합니다. BMP 형식에서는 픽셀의 각 행이 4바이트의 배수로 채워져야 합니다. 아래 코드에서는 이미지 너비에 모듈로 연산자를 사용하여 한 줄짜리 수식으로 이를 처리합니다.

  -- Number of bytes needed to pad each row to 32 bits
  padding := (4 - image_width*3 mod 4) mod 4;

또한 읽을 픽셀 데이터의 모든 행을 위한 공간을 예약해야 합니다. image 변수는 액세스 유형인 VHDL 포인터입니다. 쓰기 가능한 메모리 공간을 가리키도록 하려면 new를 사용합니다. image_height를 위한 공간을 예약하는 키워드 아래와 같이 동적 메모리의 행 수입니다.

  -- Create a new image type in dynamic memory
  image := new image_type(0 to image_height - 1);

이제 이미지 데이터를 읽을 차례입니다. 아래 목록은 행 단위로 픽셀 배열을 읽는 for 루프를 보여줍니다. 각 행에 대해 새 row_type를 위한 공간을 예약합니다. row이 가리키는 객체 변하기 쉬운. 그런 다음 예상되는 픽셀 수를 읽습니다. 먼저 파란색, 녹색, 마지막으로 빨간색입니다. 24비트 BMP 규격에 따른 순서입니다.

  for row_i in 0 to image_height - 1 loop

    -- Create a new row type in dynamic memory
    row := new row_type(0 to image_width - 1);

    for col_i in 0 to image_width - 1 loop

      -- Read blue pixel
      read(bmp_file, char);
      row(col_i).blue :=
        std_logic_vector(to_unsigned(character'pos(char), 8));

      -- Read green pixel
      read(bmp_file, char);
      row(col_i).green :=
        std_logic_vector(to_unsigned(character'pos(char), 8));

      -- Read red pixel
      read(bmp_file, char);
      row(col_i).red :=
        std_logic_vector(to_unsigned(character'pos(char), 8));

    end loop;

    -- Read and discard padding
    for i in 1 to padding loop
      read(bmp_file, char);
    end loop;

    -- Assign the row pointer to the image vector of rows
    image(row_i) := row;

  end loop;

각 라인의 페이로드를 읽은 후 추가 패딩 바이트(있는 경우)를 읽고 버립니다. 마지막으로 루프의 끝에서 새로운 동적 픽셀 행을 image의 올바른 슬롯에 할당합니다. 정렬. for 루프가 image을 종료할 때 변수는 전체 BMP 이미지에 대한 픽셀 데이터를 포함해야 합니다.

DUT 테스트

그레이스케일 모듈은 조합 로직만을 사용하므로 클럭이나 리셋 신호에 대해 걱정할 필요가 없습니다. 아래 코드는 RGB 값을 DUT 입력에 쓰는 동안 모든 행의 모든 ​​픽셀을 통과합니다. 입력 값을 할당한 후 DUT 내의 모든 델타 주기 지연이 풀리도록 10나노초 동안 기다립니다. 0보다 큰 값 또는 wait for 0 ns;도 작동합니다. 충분히 반복합니다.

  for row_i in 0 to image_height - 1 loop
    row := image(row_i);

    for col_i in 0 to image_width - 1 loop

      r_in <= row(col_i).red;
      g_in <= row(col_i).green;
      b_in <= row(col_i).blue;
      wait for 10 ns;

      row(col_i).red := r_out;
      row(col_i).green := g_out;
      row(col_i).blue := b_out;

    end loop;
  end loop;

프로그램이 wait 문에서 나올 때 DUT 출력은 이 픽셀의 그레이스케일 색상에 대한 RGB 값을 포함해야 합니다. 루프가 끝나면 DUT 출력이 입력 BMP 파일에서 읽은 픽셀 값을 대체하도록 합니다.

출력 BMP 파일 작성

이 시점에서 image의 모든 픽셀은 변수는 DUT에 의해 조작되어야 합니다. out_file에 이미지 데이터를 쓸 차례입니다. "out.bmp"라는 로컬 파일을 가리키는 개체입니다. 아래 코드에서는 입력 BMP 파일에서 저장한 헤더 바이트의 모든 픽셀을 실행하여 출력 파일에 씁니다.

  for i in header_type'range loop
    write(out_file, header(i));
  end loop;

헤더 다음에 입력 파일에서 픽셀을 읽는 순서대로 픽셀을 작성해야 합니다. 아래 목록에 있는 두 개의 중첩 for 루프가 이를 처리합니다. 각 행 다음에 deallocate을 사용합니다. 키워드는 각 행에 대해 동적으로 할당된 메모리를 해제합니다. 가비지 컬렉션은 VHDL-2019에만 포함되어 있습니다. 이전 버전의 VHDL에서는 이 줄을 생략하면 메모리 누수가 발생할 수 있습니다. for 루프의 끝에서 행 길이를 4바이트의 배수로 가져오는 데 필요한 경우 패딩 바이트를 씁니다.

  for row_i in 0 to image_height - 1 loop
    row := image(row_i);

    for col_i in 0 to image_width - 1 loop

      -- Write blue pixel
      write(out_file,
        character'val(to_integer(unsigned(row(col_i).blue))));

      -- Write green pixel
      write(out_file,
        character'val(to_integer(unsigned(row(col_i).green))));

      -- Write red pixel
      write(out_file,
        character'val(to_integer(unsigned(row(col_i).red))));

    end loop;

    deallocate(row);

    -- Write padding
    for i in 1 to padding loop
      write(out_file, character'val(0));
    end loop;

  end loop;

루프가 종료되면 image에 대한 메모리 공간을 할당 해제합니다. 변수는 아래와 같이 표시됩니다. 그런 다음 file_close를 호출하여 파일을 닫습니다. 파일 핸들에. 이것은 서브프로그램이나 프로세스가 종료될 때 파일이 암시적으로 닫히기 때문에 대부분의 시뮬레이터에서 꼭 필요한 것은 아닙니다. 그럼에도 불구하고 작업을 마친 파일을 닫는 것은 결코 잘못된 일이 아닙니다.

  deallocate(image);

  file_close(bmp_file);
  file_close(out_file);

  report "Simulation done. Check ""out.bmp"" image.";
  finish;
end process;

테스트벤치 프로세스가 끝나면 ModelSim 콘솔에 출력 이미지를 찾을 수 있는 힌트와 함께 시뮬레이션이 끝났다는 메시지를 출력합니다. finish 키워드에는 VHDL-2008이 필요하며 모든 테스트가 완료된 후 시뮬레이터를 중지하는 우아한 방법입니다.

출력 BMP 이미지

아래 이미지는 테스트벤치가 완료된 후 "out.bmp" 파일이 어떻게 보이는지 보여줍니다. BMP는 웹페이지에 임베딩하기에 적합하지 않기 때문에 이 블로그 게시물에 표시된 실제 파일은 JPEG이지만 위의 형식에 이메일 주소를 남겨두면 "boeing.bmp" 파일을 포함한 전체 프로젝트가 포함된 zip을 얻을 수 있습니다.

마지막 발언

FPGA의 이미지 처리를 위해 RGB 대신 YUV 색상 인코딩 방식이 자주 사용됩니다. YUV에서 루마(휘도) 구성요소 Y는 색상 정보와 별도로 유지됩니다. YUV 형식은 인간의 시각적 인식에 더 가깝게 매핑됩니다. 다행히 RGB와 YUV 사이를 쉽게 변환할 수 있습니다.

RGB를 CMYK로 변환하는 것은 일대일 픽셀 공식이 없기 때문에 조금 더 복잡합니다.

이러한 이국적인 인코딩 체계를 사용할 때의 또 다른 대안은 고유한 이미지 파일 형식을 만드는 것입니다. ".yuv" 또는 ".cmyk" 접미사가 붙은 사용자 지정 파일 형식으로 픽셀 배열을 저장하기만 하면 됩니다. 픽셀이 어떤 이미지 형식을 가질지 알면 헤더가 필요하지 않습니다. 테스트벤치에서 읽어보세요.

소프트웨어 변환을 설계 흐름에 항상 통합할 수 있습니다. 예를 들어, 시뮬레이션이 시작되기 전에 표준 명령줄 이미지 변환 소프트웨어를 사용하여 PNG 이미지를 BMP 형식으로 자동 변환합니다. 그런 다음 이 기사에서 배운 대로 VHDL을 사용하여 테스트벤치에서 읽으십시오.


VHDL

  1. 홀로그램
  2. C# 사용
  3. C 파일 처리
  4. 자바 파일 클래스
  5. TEXTIO를 사용하여 파일에서 RAM을 초기화하는 방법
  6. Java BufferedReader:예제를 사용하여 Java에서 파일을 읽는 방법
  7. Python JSON:인코딩(덤프), 디코딩(로드) 및 JSON 파일 읽기
  8. Verilog 파일 IO 작업
  9. C - 헤더 파일
  10. 플렌옵틱 카메라