OZ1NG의 뽀나블(Pwnable)

[BMP] BMP 파일 포맷 - 24bit BMP(BMP24) 본문

Laboratory

[BMP] BMP 파일 포맷 - 24bit BMP(BMP24)

OZ1NG 2022. 6. 21. 01:53

[*] 바이너리 파일을 BMP로 바꾸어 머신러닝 CNN로 돌리기 위해, 그리고 만드는 BMP 구조를 내 입맛대로 바꾸기 위하여 BMP 파일 구조를 공부하게 되었다.

[그림0] - 만들어진 24bit BMP 이미지 예시

[*] BMP 24?

24bit BMP라고도 불리며 이는 한 픽셀을 표현하는데 사용하는 비트 수가 24bit라는 의미이다.

사용하는 비트 수가 많은 만큼 다양한 색을 표현할 수 있기 때문에 BMP 종류 중 가장 원본에 가까운 이미지를 만들 수 있다

 

[*] BMP 24 구조

BMP24는 기본적으로 Bitmap File Header, Bitmap Info Header, 실제 이미지 데이터(Pixel 데이터)로 구성된다.

또한 모든 필드들의 바이트 오더는 Little Endian이다.

한 픽셀은 24bit(3byte)로 표현한다.

 

[+] BITMAPFILEHEADER

BITMAPFILEHEADER는 이름처럼 비트맵 파일의 헤더이다.
BMP 파일의 종류에 상관 없이 공통적으로 들어가 있고 항상 14byte의 크기를 갖는다.

 

BITMAPFILEHEADER 구조체는 다음과 같다.

typedef struct tagBITMAPFILEHEADER {
  WORD  bfType;
  DWORD bfSize;
  WORD  bfReserved1;
  WORD  bfReserved2;
  DWORD bfOffBits;
} BITMAPFILEHEADER, *PBITMAPFILEHEADER;

- bfType : BMP의 시그니처 부분

  + 크기 : 2byte

  + 값 : 0x424d("BM") - 고정

- bfSize : BMP 파일 전체 크기

  + 크기 : 4byte

  + 값 : 유동적

- bfReserved1 : 예약된 공간

  + 크기 : 2byte

  + 값 : 0x0(0) - 고정

- bfReserved2 : 예약된 공간

  + 크기 : 2byte

  + 값 : 0x0(0) - 고정

- bfOffBits : 비트맵 데이터(픽셀 데이터)의 시작 위치

  + 크기 : 4byte

  + 값 : 0x36 - 고정

 

[+] BITMAPINFOHEADER

BITMAPINFOHEADER는 비트맵 파일의 실질적인 정보들에 대한 헤더 파일이다.

해당 부분은 Windows Version 3부터 사용되고 만약, OS/2라면 BITMAPCOREHEADER가 해당 부분에 대신 들어가게 된다. (해당 글에서는 BITMAPINFOHEADER만 설명하겠다.)
Windows Version 3계열이라면 BMP 파일의 종류에 상관 없이 공통적으로 들어가 있고 항상 40byte의 크기를 갖는다. 

 

BITMAPINFOHEADER 구조체는 다음과 같다.

typedef struct tagBITMAPINFOHEADER {
  DWORD biSize;
  LONG  biWidth;
  LONG  biHeight;
  WORD  biPlanes;
  WORD  biBitCount;
  DWORD biCompression;
  DWORD biSizeImage;
  LONG  biXPelsPerMeter;
  LONG  biYPelsPerMeter;
  DWORD biClrUsed;
  DWORD biClrImportant;
} BITMAPINFOHEADER, *PBITMAPINFOHEADER;

- biSize : BITMAPINFOHEADER 필드의 크기

  + 크기 : 4byte

  + 값 : 0x28(40)byte - 고정

- biWidth : 비트맵 이미지의 가로 크기(픽셀 개수)

  + 크기 : 4byte

  + 값 : 유동적

- biHeight : 비트맵 이미지의 세로 크기(픽셀 개수)

  + 크기 : 4byte

  + 값 : 유동적

  + 특징 : 값이 양수면 이미지의 상하가 뒤집혀진 상태로 저장되어 있음을 뜻한다. 보통 양수 값이 저장된다.
               즉, 기본적으로 픽셀은 이미지의 상하가 뒤집혀진 상태로 저장이 된다는 뜻이다.

[그림1] - 이미지 픽셀 데이터 저장 순서

- biPlanes : 사용하는 색상 판의 수를 뜻

  + 크기 : 2byte

  + 값 : 0x1 - 고정

- biBitCount : 픽셀 하나를 표현하는 비트 수. 24bit BMP이므로 값이 24가 된다.

  + 크기 : 2byte

  + 값 : 0x18(24) - 고정

- biCompression : 압축 방식을 뜻하지만 BMP는 별개의 압축 방식을 지원하지 않아 0으로 고정이다

  + 크기 : 4byte

  + 값 : 0x0(0) - 고정

- biSizeImage : 헤더 부분들을 제외한, 순수한 비트맵 이미지의 픽셀 데이터 크기이다. 압축되지 않은 크기를 뜻한다.

  + 크기 : 4byte

  + 값 : 유동적

- biXPelsPerMeter : 그림의 가로 해상도(미터당 픽셀)을 나타낸다. 그냥 0으로 고정해도 상관 없다.

  + 크기 : 4byte

  + 값 : 0x0 - 원하면 고정

- biYPelsPerMeter : 그림의 세로 해상도(미터당 픽셀)을 나타낸다. 그냥 0으로 고정해도 상관 없다.

  + 크기 : 4byte

  + 값 : 0x0 - 원하면 고정

- biClrused : 색상 테이블에서 실제 사용되는 색상 수. 그냥 0으로 고정해도 상관 없다.

  + 크기 : 4byte

  + 값 : 0x0 - 원하면 고정

- biClrImportant : 비트맵을 표현하기 위해 필요한 색상 인덱스 수. 그냥 0으로 고정해도 상관 없다.

  + 크기 : 4byte

  + 값 : 0x0 - 원하면 고정

 

 

[+] Pixel Data Field

실제 픽셀 데이터가 들어가는 부분이다.
(이 부분에 대한 정확한 이름은 모르겠다. - 아시는 분은 댓글로 알려주시면 감사하겠습니다... ㅠㅠ)

 

BMP24의 경우 한 픽셀을 24bit(3byte)로 표현을 하고 각 순서는 다음과 같다.

[그림2] - 1 Pixel

왼쪽부터 Red, Green, Blue(빛의 3원색)에 대한 색의 정도를 나타내고 각 부분당 8bit의 크기를 가진다.

즉, 각 부분당 0~255까지의 값을 가질 수 있다.

값이 0이면 어두운 색(검정색)에 가까워지고, 255에 가까울 수록 해당 색을 뚜렷하게 나타낸다.

(따라서 255,255,255면 흰색, 0,0,0이면 검정색, 255,0,0이면 빨강색이다.)

 

해당 부분(또는 BMP)의 특징은 한 행에 해당하는 모든 픽셀 바이트의 길이가 4바이트로 정렬되어야 한다는 것이다.

한 행의 길이가 4바이트 단위가 아닌 경우 남은 부분은 padBytes라는 이름으로 패딩된다.

 

- padBytes : 한 행에 대한 패딩 값

  + 크기 : 0~3 byte : (length(한 행의 픽셀 데이터 길이) % 4)

  + 값 : 뭐가 들어가든 상관 없지만 보통 0으로 통일된다.

'Laboratory' 카테고리의 다른 글

[BMP] B2B (BYTE to BMP) 모듈  (0) 2022.06.29
[BMP] BMP 파일 포맷 - GrayScale BMP  (0) 2022.06.21
[Lab] [Browser] Chromiun - Build  (0) 2021.10.01
[Lab] Segment Register 정리 (좀 자세히...)  (0) 2021.06.04
[Lab] TLS/TCB 정리  (0) 2021.06.03
Comments