PNG 파일 구조
File signature
png 파일에 대한 간략한 구조이다. png 파일에 반드시 있어야 하는 청크만 구조화 시켰다.
89 50 4E 47 0D 0A 1A 0A
- png 파일은 8바이트 크기의 헤더 시그니처를 가짐
- 이중
50 4E 47
이 ASCII 값으로 PNG 이므로, Hex viewer에서 PNG 파일을 열었을 때 쉽게 확인 가능
실습에 사용한 png 파일이다.
파일 시그니처를 보면 위와 같이 89 50 4E 47 0D 0A 1A 0A
와 PNG ASCII 문자열이 보인다.
49 45 4E 44 AE 42 60 82
- png 파일은 푸터 시그니처도 존재
Chunk
- png 파일은 N 개의 청크로 구성
{
Length (4 byte), # Chunk의 크기
Chunk Type (4 byte), # Chunk의 타입
Chunk Data (length byte), # Chunk 내용
CRC (4byte) # 오류 검사를 위한 값
}
- 청크의 타입이 여러가지가 있고, 그 중 모든 png 파일에 반드시 포함되어야 하는 청크 세가지가 존재
- IHDR
- IDAT
- IEND
- 그 외 청크는 png 파일의 타입에 따라 요구되거나, 또는 메타데이터를 저장하는데 사용
IHDR
- png 파일의 가장 앞에 위치하는 청크(시그니처 바로 뒤에 나옴)
- 가로, 세로, 비트 깊이, 색 타입, 압축 메소드, 필터링 메소드, 인터레이스 메소드에 대한 정보 담김
{
Length : 00 00 00 0D (13 byte),
Chunk Type : IHDR,
Chunk Data ( 13 byte ),
{
Width (4 byte),
Height (4 byte),
Bit depth (1 byte),
Color Type (1 byte),
Compression method (1 byte),
Filter method (1 byte),
Interlace method (1 byte),
}
CRC
}
- IHDR 청크의 데이터 길이는 항상 13바이트
Width & Height
- 이미지의 폭과 넓이를 지정
- 일반적으로 이미지뷰어, 브라우저 등은 이 값을 바탕으로 이미지 데이터를 디코딩하고 출력
- 이 부분을 조작하면 이미지가 이상해지거나 이미지의 아래 부분을 감추는 것도 가능
Color type & Bit depth
- Color type은 png 이미지의 색상을 어떻게 구성할 것인지를 정함
- Bit depth는 하나의 채널이 몇 비트로 구성될 지를 정함
- 이미지의 한 픽셀은 하나 또는 여러 개의 채널로 구성될 수 있음
- ex) RGB Color type
PNG image type | Color Type | Allowed bit depths | interpretation |
---|---|---|---|
Grayscale | 0 | 1, 2, 4, 8, 16 | Grayscale Data |
Truecolor | 2 | 8, 16 | RGB Data |
Indexed-color | 3 | 1, 2, 4, 8 | Palette Data |
Grayscale with alpha | 4 | 8, 16 | Grayscale + Alpha Data |
Truecolor with alpha | 6 | 8, 16 | RGB + Alpha Data |
0번은 회색조, 2번은 RGB, 3번은 색인 색상, 4번은 투명도가 있는 회색조, 6번은 투명도가 있는 RGB를 의미
압축 메소드, 필터 메소드, 인터레이스 메소드
- 압축 메소드는 현재까지 필터링 방식이 0(Deflate) 한 가지이고, 필터링 메소드도 0(Adaptive Filtering) 한가지
- 현재까지 png에서 표준으로 정의된 인터레이스 메소드는 0(No interlace), 1(Adam interlace) 두가지
IDAT
- 실제로 이미지 데이터가 들어가는 청크
{
Length (4 byte),
Chunk Type : IDAT(4 byte),
Chunk Data (Length byte),
{
Filtered, Compressed Data
.
.
}
CRC (4 byte)
}
- 한 개의 png 파일은 여러 개의 IDAT 청크를 가질 수 있는데, 이는 데이터를 적절한 사이즈로 나누어 전송하기 위함 (이때 IDAT 청크가 있어야만 이미지 디코딩 가능)
- 즉 하나의 IDAT 청크라도 없으면 압축 이미지 디코딩 불가
- 한 IDAT 청크당 65536 바이트의 데이터 크기를 가짐
- png가 전체 이미지 데이터를 한꺼번에 압축한 뒤, 여러 IDAT 청크에 나누어 담는 방식을 사용하기 때문
인코딩 과정
- 픽셀 데이터 → Filter → Compression → IDAT chunk data
디코딩 과정
- IDAT chunk data → Decompression → Unfilter → Pixel data
Filtering
- 원시 이미지 데이터의 압축률을 높이기 위해 데이터를 가공하는 작업
IEND
- 이미지의 맨 뒤에 위치하는 청크로 png 파일의 끝을 나타냄
{
Length : 00 00 00 00 (0 byte),
Chunk Type : IEND,
Chunk Data (0 byte),
CRC
}
- 데이터를 담는 목적으로 사용 X
- Length의 값은 언제나 0
ZIP 파일 구조
File Area
- File Entry의 집합으로, 하나의 File Entry는 압축 파일에 포함된 하나의 파일 이름, 파일 데이터, 파일 메타 데이터 등을 포함한 Entry 의미
File Entry Structure
하나의 File Entry는 Local Header, File Name, File Date를 포함
위는 File Entry의 필드를 직접 만들어 보았다.
Central Directory Area
- Directory Entry의 집합
- 하나의 Directory Entry는 하나의 File Entry와 쌍을 이루며 File Entry의 주소를 포함하여 파일의 빠른 접근을 가능하게 함
Directory Entry Structure
- 하나의 Directory Entry는 Central Directory Header, File Name 포함
End of Central Directory
- Central Directory의 시작 위치, 크기, 압축 파일에 포함된 파일의 총 개수 등의 정보를 포함한 영역
End of Central Directory Structure
- 파일 카빙 시 Comment Length만큼을 포함한 영역을 카빙해야 함
File Access
- 압축파일에서 특정 파일에 접근할 때의 과정은 다음과 같음
- End of Central Directory 영역에서 시작해서 Central Directory Header 주소를 참조하여 Central Directory Header로 이동
- 이후에 접근하려는 특정 파일에 맞는 Directory Entry로 이동하고 해당 Directory Entry의 Local Header Offset을 참조하여 특정 File Entry에 접근
실습
직접 파일 몇개를 압축해보고 HxD로 열어보자.
이 두 이미지 파일을 압축시켜 HxD로 봐보자.
image.png와 image2.png가 존재하는 것을 볼 수 있다. 추가로 시그니처도 확인 가능하다.