JFIF :
지금까지 설명한 원리에 따라 JPEG 이미지가 저장이 되는데 JPEG 파일의 실제 구조는 어떠한지 알아보자. 이미 설명했듯이 JPEG 파일 구조란 JFIF(JPEG File Interchange Format)을 의미한다. JPEG 파일은 그림 1과 같이 여러 개의 블록으로 나뉘어져 있다.
SOI (Start Of Image) |
APP0 JFIF Marker |
추가 APP Marker (APP0 ~ APP15)
또는 주석 (COM) marker |
DQT (Define Quantization Tables) |
SOF (Start Of Frame) |
DHT (Define Huffman Tables) |
SOS (Start Of Scan) |
스캔 데이터 |
EOI (End Of Image) |
그림 1 JFIF의 구조
각 블록은 Marker에 의해 구분된다. Marker는 &HFF로 시작되는 두 바이트 데이터로 marker 하나로 끝나는 것도 있고 marker 뒤에 추가 데이터가 더 붙는 것도 있다. 추가 데이터가 더 붙는 경우 marker 뒤에 2바이트의 데이터 길이가 오고 그 다음 추가 데이터가 온다. 데이터 길이는 데이터 길이 필드를 포함한 길이다. 한가지 주의할 것이 지금까지 살펴본 그래픽 파일에서는 상위 바이트와 하위 바이트의 순서가 바뀌어서 저장되어 있는데 JPEG 파일에서는 그 순서가 뒤바뀌어서 저장되지 않는다는 점이다. 예를 들어 &H12 &H3F 순으로 저장되어 있다면 &H3F12가 아니고 &H123F를 가리키는 것이다.
JFIF에서 사용되는 marker는 표 1과 같다.
분류 |
값 |
심볼 |
설명 |
추가 데이터 없음 |
FFD0~FFD7 |
RST0~RST7 |
Restart marker |
FFD8 |
SOI |
Start Of Image |
FFD9 |
EOI |
End Of Image |
추가 데이터 있음 |
FFC0~FFC2 |
SOF0~SOF2 |
Start Of Frame |
FFC4 |
DHT |
Deine Huffman Tables |
FFDA |
SOS |
Start Of Scan |
FFDB |
DQT |
Define Quantization Tables |
FFDD |
DRI |
Define Restart Interval |
FFE0~FFEF |
APP0~APP15 |
Application specific data |
FFFE |
COM |
Commnet |
표 1 JFIF에서 사용되는 marker
JPEG 표준에는 이보다 더 많은 marker들이 정의되어 있으나 JFIF에서는 거의 쓰이지 않는다. 각 블록을 더 자세히 살펴보자.
SOI와 APP0 JFIF Marker : 파일의 맨 처음 오는 marker들로 주로 JFIF임을 확인하는 용도로 사용된다. 그 구조는 표 2와 같다.
이름 |
크기 |
설명 |
SOI marker |
2 |
항상 FF D8 |
APP0 marker |
2 |
항상 FF E0 |
Data length |
2 |
추가 데이터 길이. 바이트 단위. 상위 바이트, 하위 바이트 순으로 저장되며 Data length 필드를 포함한 길이를 나타낸다. |
Identifier |
5 |
항상 4A 46 49 46 00. JFIF임을 나타낸다. |
Major version ID |
1 |
버전 번호. |
Minor version ID |
1 |
버전 번호. |
Units |
1 |
그 다음 오는 X, Y 해상도의 단위를 나타냄.
0 – 해상도 사용 안함 1 – 단위 인치 당 픽셀 수 2 – 단위 cm 당 픽셀 수 |
Xdensity |
2 |
가로 해상도 |
Ydensity |
2 |
세로 해상도 |
Xthumbnail |
1 |
미리 보기 이미지의 폭. 미리 보기가 없으면 0. |
Ythumbnail |
1 |
미리 보기 이미지의 높이. 미리 보기가 없으면 0. |
Thumbnail |
가변 |
미리 보기 이미지. RGB 컬러 순으로 픽셀 데이터가 저장되어 있다. |
표 2 SOI와 APP0 JFIF marker의 구조
추가 보조 Marker : APP0 marker 외에 미리 보기 이미지를 추가로 더 넣거나 주석을 달기 위해 몇 가지 marker가 더 올 수 있다. 보통 이들 marker들은 그림 이미지 자체에 전혀 영향을 주지 않으며 어플리케이션 프로그램에서 보조 자료로 쓰일 뿐이다. marker 뒤에 추가 데이터 길이 필드가 오는데 이를 이용해 다음 marker로 건너 뛸 수 있다.
DQT marker : DQT는 양자화 테이블(Quantization table)을 보관하는 블록이다. 표 3과 같은 구조로 되어 있다.
이름 |
크기 |
설명 |
DQT marker |
2 |
항상 FF DB |
Data length |
2 |
추가 데이터 길이. |
Quantization table |
|
양자화 테이블. 최대 4개의 테이블을 가질 수 있다. |
표 3 DQT marker의 구조
JFIF는 최대 4개의 양자화 테이블을 보관할 수 있다. 각각의 양자화 테이블 구조는 표 4와 같다. 테이블 값은 8비트 샘플링의 경우 1바이트, 12비트 샘플링의 경우 2바이트 크기를 가진다.
Table Identifier |
1 |
상위 4비트 : 테이블 값 크기. 0= 1바이트. 1=2바이트. 하위 4비트 : 테이블 ID. 0~3 사이의 값을 가진다. |
Table |
64 또는 128 |
양자화 테이블. 8 x 8 테이블이 지그재그 순서로 저장되어 있다. (그림 5‑28 참고) |
표 4 양자화 테이블의 구조
그림 2 양자화 테이블 값이 저장된 순서
SOF marker : SOF는 그림 이미지의 크기 및 샘플링에 관한 정보를 보관하고 있다. 표 5는 SOF 블록의 구조이다.
이름 |
크기 |
설명 |
SOF marker |
2 |
항상 FF C0 ~ FF C2
FFC0 – baseline FFC1 – extened sequential FFC2 - progressive |
Data length |
2 |
추가 데이터 길이. |
Sampling precision |
1 |
샘플링 비트 수 8 또는 12 |
Image height |
2 |
이미지 높이. 픽셀 단위. |
Image width |
2 |
이미니 폭. 픽셀 단위. |
No fo components |
1 |
Y, Cb, Cr 성분 수. 1 ~ 3. |
Component specific |
|
각 성분에 대한 정보. |
표 5 SOF marker 구조
JFIF는 Y, Cb, Cr 세 가지 성분 중 하나 또는 3가지 모두를 저장할 수 있다. 각 성분에 대한 정보는 표 6과 같은 구조로 저장되어 있다.
이름 |
크기 |
설명 |
Component ID |
1 |
각 성분을 구분하기 위한 ID. 0~255 사이의 값을 가질 수 있으나 JFIF에서는 Y는 1, Cb는 2, Cr은 3으로 고정되어 있다. |
Sampling Frequency |
1 |
상위 4비트 : 해당 성분의 가로 샘플링 주기 (1~4)
하위 4비트 : 해당 성분의 세로 샘플링 주기 (1~4) |
Quantization table ID |
1 |
해당 성분에서 사용할 양자화 테이블의 ID 0 ~ 3의 값을 가진다. |
표 6 YCbCr 성분에 대한 정보
SOF는 JPEG 파일 안에 오직 하나만 존재할 수 있다.
DHT marker : DHT는 Huffman 코드 테이블을 보관하고 있는 블록이다. Huffman 코드 테이블은 AC 계수용, DC 계수용이 따로 보관되며 각각 최대 4개의 테이블을 가질 수 있다. 각 테이블의 구조는 표 7과 같다.
이름 |
크기 |
설명 |
DHT marker |
2 |
항상 FF C4 |
Data length |
2 |
추가 데이터길이. |
Huffman table |
|
Huffman table 구조 참고 |
하나의 Huffman table 구조
이름 |
크기 |
설명 |
Table ID |
1 |
상위 4비트 : Table class. 0은 DC 1은 AC 테이블을 의미.
하위 4비트 : Table ID. 0 ~ 3의 값을 가진다. |
Codelength Counter |
16 |
코드 길이가 1 ~16인 코드의 개수를 보관하고 있다. |
Symbols |
가변 |
Huffman 코드 순서대로 코드가 가리키는 실제 데이터를 보관하고 있다. 전체 크기는 codelength counter의 총 합. |
표 7 DHT marker
SOS marker : SOS는 각 성분들이 어떤 Huffman table을 사용할지 알려주는 블록이다. 그 구조는 표 8과 같다.
이름 |
크기 |
설명 |
SOF marker |
2 |
항상 FF DA |
Data length |
2 |
추가 데이터 길이. |
Component count |
1 |
성분 개수 |
Scan description |
|
각 성분이 사용할 Huffman table의 ID |
Spectral selection start |
1 |
DCT 를 최적화할 때 사용하는 값. |
Spectral selection end |
1 |
Successive approximation |
1 |
표 8 SOS marker
Scan description은 성분의 개수만큼 있는데 각각의 구조는 표 9와 같다.
이름 |
크기 |
설명 |
Component ID |
1 |
각 성분을 구분하는 ID |
Huffman table ID |
1 |
상위 4비트 : 해당 성분이 사용할 DC Huffman 테이블의 ID
하위 4비트 : 해당 성분이 사용할 AC Huffman 테이블의 ID |
표 9 각 성분의 scan description
SOS가 시작되기 전에 최소한 하나 이상의 DHT, DQT와 하나의 SOF가 있어야 한다.
스캔 데이터 : SOS 바로 다음에 스캔 데이터 블록이 오게 되는데 스캔 데이터는 픽셀들의 색 정보를 샘플링-DCT-양자화-Huffman coding 과정을 거쳐 만들어낸 데이터이다. 이렇게 해서 만들어진 스캔 데이터를 다시 원래 픽셀 정보로 바꾸려면 역으로 Huffman decoding-역양자화(Dequantization)-IDCT-업 샘플링 과정을 거치면 된다.
Restart marker : restart marker (RST)는 유일하게 스캔 데이터 안에 존재하는 marker로 손상된 JPEG을 최대한 복원하기 위해 사용하는 marker이다.
SOS 이전에 DRI(Define Restart Interval) marker로 restart 간격을 정의를 한다. DRI marker의 구조는 표 10과 같다.
이름 |
크기 |
설명 |
DRI marker |
2 |
항상 FF DD |
Data length |
2 |
추가 데이터 길이. |
Restart interval |
2 |
Restart 간격. 0이면 restart marker(RST)가 쓰이지 않음을 의미. |
표 10 Restart marker
DRI에 정의된 restart 간격이 0보다 크면 그 간격만큼의 MCU 마다 RST marker가 놓이게 된다. 예를 들어 restart 간격이 N이라면 그림 3과 같이 N개의 MCU 데이터 마다 RST marker가 놓인다.
그림 3 RST marker
RST marker는 RST0부터 RST7까지 8개가 있는데 순차적으로 나타나며 RST7 다음에는 RST0이 다시 나오게 된다.
|