PicScrub logoPicScrub
형식 목록으로 돌아가기

TIFF 형식

Tagged Image File Format

헤더 구조

TIFF는 이미지 메타데이터의 할아버지 격이에요. JPEG 안에서 보는 EXIF 데이터도 사실은 파일 속에 들어간 TIFF 구조입니다. TIFF를 이해하면 대부분의 이미지 메타데이터가 어떻게 돌아가는지 알게 되는 셈이죠.

파일은 8바이트 헤더로 시작하는데, 여기서 두 가지 중요한 걸 알려 줍니다. 바이트 순서(Intel이냐 Motorola냐)와 첫 IFD가 어디 있는지죠. 그다음부터는 계속 포인터를 따라가는 일입니다.

TIFF 파일 구조

Header
IFD0
Strip Data
EXIF IFD
GPS IFD
Header
8바이트
바이트 순서 + 매직 넘버 + IFD 오프셋
IFD0
200바이트
메인 이미지 디렉터리
Strip Data
가변 길이
이미지 픽셀 데이터
EXIF IFD
500바이트
EXIF 하위 디렉터리
GPS IFD
100바이트
GPS 하위 디렉터리

TIFF 헤더

바이트 순서 (II = 리틀엔디언)
매직 넘버 (42)
첫 IFD 오프셋
OffsetHexASCII
0000
49492A0008000000
II*.....

바이트 순서

49 49 (II)

Intel:리틀엔디언 (낮은 자리 바이트가 먼저)

4D 4D (MM)

Motorola:빅엔디언 (높은 자리 바이트가 먼저)

IFD의 구조

IFD는 Image File Directory의 약자인데, 그냥 목차라고 생각하면 돼요. 태그를 쭉 늘어놓은 목록이고, 각 태그가 어떤 데이터를 가리킵니다. 영리한 점은 IFD가 다른 IFD를 가리킬 수 있어서 트리 구조가 만들어진다는 거예요.

IFD 배치

2바이트항목 개수 (태그의 수)
12 × N 바이트태그 항목 (하나에 12바이트)
4바이트다음 IFD 오프셋 (없으면 0)

태그 항목의 구조 (12바이트)

Tag IDTypeCountValue/Offset
2바이트2바이트4바이트4바이트

데이터가 4바이트 안에 들어가면 값 필드에 그대로 저장합니다. 그렇지 않으면 값 필드에 데이터가 있는 위치의 오프셋이 들어가요.

태그 타입

TIFF는 타입이 엄격한 형식이에요. 각 태그는 무엇이 들어 있는지뿐 아니라 바이트를 어떻게 해석해야 하는지도 함께 지정합니다. 그래서 TIFF를 제대로 파싱하려면 타입 체계를 알아야 해요.

ID이름크기설명
1BYTE1부호 없는 8비트 정수
2ASCII1null로 끝나는 문자열 (8비트)
3SHORT2부호 없는 16비트 정수
4LONG4부호 없는 32비트 정수
5RATIONAL8LONG 두 개: 분자/분모
6SBYTE1부호 있는 8비트 정수
7UNDEFINED1원시 바이트 (바이너리 데이터)
8SSHORT2부호 있는 16비트 정수
9SLONG4부호 있는 32비트 정수
10SRATIONAL8SLONG 두 개: 부호 있는 분자/분모
11FLOAT4IEEE 32비트 부동소수점
12DOUBLE8IEEE 64비트 배정밀도
13IFD4중첩된 IFD를 가리키는 포인터

값 저장 규칙

크기 × 개수 ≤ 4바이트이면 값을 4바이트짜리 값 필드에 그대로 저장합니다. 그보다 크면 값 필드에는 데이터가 저장된 위치를 가리키는 오프셋이 들어갑니다.

IFD 오프셋 계산

TIFF 파싱에서 제일 까다로운 건 오프셋 사슬을 따라가는 일이에요. 모든 값이 파일 시작을 기준으로 하기 때문에, 파일 안을 이리저리 많이 건너뛰게 됩니다. 계산은 이렇게 해요:

// IFD0 위치
IFD0_offset = bytes[4:8] // TIFF 헤더에서 가져옴
// 다음 IFD 위치 (예: 썸네일용 IFD1)
next_IFD = IFD0_offset + 2 + (entry_count × 12) + 4
// SubIFD 위치 (EXIF, GPS)
subIFD_offset = tag_value // 포인터 태그(0x8769, 0x8825)에서 가져옴

중요한 태그

이미지 데이터 태그 (남김)

0x0100:ImageWidth
0x0101:ImageLength
0x0102:BitsPerSample
0x0103:Compression
0x0111:StripOffsets
0x0117:StripByteCounts

메타데이터 태그 (지움)

0x010F:Make (카메라 제조사)
0x0110:Model (카메라 모델)
0x0132:DateTime
0x013B:Artist
0x8298:Copyright
0x9003:DateTimeOriginal

포인터 태그 (하위 IFD)

0x8769:ExifIFDPointer
0x8825:GPSInfoIFDPointer
0xA005:InteroperabilityIFDPointer

하위 IFD

메인 IFD(IFD0)에는 하위 디렉터리를 가리키는 "포인터 태그"가 들어 있는 경우가 많습니다. 이렇게 해서 EXIF, GPS를 비롯한 메타데이터를 의미 있는 묶음으로 정리하면서도 메인 IFD를 깔끔하게 유지해요.

EXIF SubIFD

카메라 관련 메타데이터가 들어 있습니다. 노출, 조리개, ISO, 초점 거리, 플래시, 화이트 밸런스 등이죠.

GPS SubIFD

위치 정보가 들어 있습니다. 위도, 경도, 고도, 시각, 위성 수, 속도, 방향까지요. 프라이버시에 가장 위험한 부분이에요.

메이커 노트

제조사 고유의 카메라 데이터입니다. 형식은 제조사마다 다르고, 일련번호, 펌웨어 버전, 사용자 설정이 들어 있을 수 있어요.

PicScrub이 TIFF를 처리하는 방법

1

헤더 파싱

바이트 순서(II/MM)를 판별하고 첫 IFD 위치를 찾습니다

2

태그 허용 목록 만들기

이미지를 그리는 데 꼭 필요한 태그를 추려냅니다

3

IFD 항목 걸러내기

메타데이터 태그를 지우고 하위 IFD 포인터를 0으로 만듭니다

4

파일 다시 쓰기

깨끗해진 IFD와 그대로 복사한 이미지 데이터로 TIFF를 다시 조립합니다

오프셋 재계산

TIFF는 파일 오프셋을 아주 많이 씁니다. 그래서 메타데이터를 지운 뒤에는 파일이 온전하게 유지되도록 PicScrub이 모든 오프셋을 다시 계산해야 해요.