PicScrub logoPicScrub
Quay lại danh sách định dạng

Định dạng TIFF

Tagged Image File Format

Cấu trúc phần đầu file

TIFF là ông tổ của siêu dữ liệu ảnh. Khi bạn thấy dữ liệu EXIF trong một file JPEG, thực chất đó là một cấu trúc TIFF nằm gọn bên trong. Hiểu TIFF nghĩa là hiểu cách phần lớn siêu dữ liệu ảnh vận hành.

File bắt đầu bằng một header 8 byte cho bạn biết hai điều quan trọng: thứ tự byte (Intel hay Motorola) và chỗ tìm IFD đầu tiên. Từ đó trở đi, tất cả là chuyện lần theo con trỏ.

Cấu trúc file TIFF

Header
IFD0
Strip Data
EXIF IFD
GPS IFD
Header
8 byte
Thứ tự byte + số nhận dạng + offset IFD
IFD0
200 byte
Thư mục ảnh chính
Strip Data
Độ dài thay đổi
Dữ liệu điểm ảnh
EXIF IFD
500 byte
Thư mục con chứa EXIF
GPS IFD
100 byte
Thư mục con chứa GPS

Header TIFF

Thứ tự byte (II = little-endian)
Số nhận dạng (42)
Offset của IFD đầu tiên
OffsetHexASCII
0000
49492A0008000000
II*.....

Thứ tự byte

49 49 (II)

Intel:little-endian (byte ít quan trọng nhất đứng trước)

4D 4D (MM)

Motorola:big-endian (byte quan trọng nhất đứng trước)

Cấu trúc IFD

IFD là viết tắt của Image File Directory, nhưng bạn cứ hình dung nó như một mục lục. Đó là một danh sách phẳng các thẻ, mỗi thẻ trỏ tới một mẩu dữ liệu. Điểm khéo là IFD có thể trỏ tới IFD khác, tạo thành một cấu trúc cây.

Bố cục của một IFD

2 byteSố lượng mục (số thẻ)
12 × N byteCác mục thẻ (mỗi mục 12 byte)
4 byteOffset của IFD kế tiếp (bằng 0 nếu không còn)

Cấu trúc một mục thẻ (12 byte)

ID thẻKiểuSố lượngGiá trị/Offset
2 byte2 byte4 byte4 byte

Nếu dữ liệu vừa trong 4 byte thì nó được lưu thẳng vào trường giá trị. Nếu không, trường đó chứa offset trỏ tới nơi cất dữ liệu.

Các kiểu thẻ

TIFF định kiểu rất chặt. Mỗi thẻ không chỉ nói nó chứa gì, mà còn nói phải hiểu các byte đó ra sao. Vì vậy bạn phải nắm hệ thống kiểu thì mới đọc TIFF cho đúng.

IDTênKích thướcMô tả
1BYTE1Số nguyên 8 bit không dấu
2ASCII1Chuỗi kết thúc bằng null (8 bit)
3SHORT2Số nguyên 16 bit không dấu
4LONG4Số nguyên 32 bit không dấu
5RATIONAL8Hai số LONG: tử số/mẫu số
6SBYTE1Số nguyên 8 bit có dấu
7UNDEFINED1Byte thô (dữ liệu nhị phân)
8SSHORT2Số nguyên 16 bit có dấu
9SLONG4Số nguyên 32 bit có dấu
10SRATIONAL8Hai số SLONG: tử/mẫu có dấu
11FLOAT4Số thực IEEE 32 bit
12DOUBLE8Số thực IEEE 64 bit
13IFD4Con trỏ tới IFD lồng bên trong

Quy tắc lưu giá trị

Nếu kích thước × số lượng ≤ 4 byte thì giá trị được lưu thẳng vào trường 4 byte. Nếu không, trường đó chứa offset trỏ tới nơi dữ liệu được cất trong file.

Cách tính offset của IFD

Phần khó nhất khi đọc TIFF là lần theo chuỗi offset. Mọi thứ đều tính từ đầu file, và bạn sẽ phải nhảy qua nhảy lại khá nhiều. Phép tính như sau:

// Vị trí của IFD0
IFD0_offset = bytes[4:8] // Lấy từ header TIFF
// Vị trí IFD kế tiếp (ví dụ IFD1 cho ảnh thu nhỏ)
next_IFD = IFD0_offset + 2 + (entry_count × 12) + 4
// Vị trí SubIFD (EXIF, GPS)
subIFD_offset = tag_value // Lấy từ thẻ con trỏ (0x8769, 0x8825)

Những thẻ quan trọng

Thẻ dữ liệu ảnh (được giữ lại)

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

Thẻ siêu dữ liệu (bị xóa)

0x010F:Make (hãng sản xuất máy ảnh)
0x0110:Model (model máy ảnh)
0x0132:DateTime
0x013B:Artist
0x8298:Copyright
0x9003:DateTimeOriginal

Thẻ con trỏ (tới các sub-IFD)

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

Các SubIFD

IFD chính (IFD0) thường chứa các "thẻ con trỏ" tham chiếu tới những thư mục con. Nhờ vậy EXIF, GPS và các siêu dữ liệu khác được gom thành từng nhóm hợp lý, còn IFD chính vẫn gọn gàng.

SubIFD chứa EXIF

Chứa siêu dữ liệu riêng của máy ảnh: phơi sáng, khẩu độ, ISO, tiêu cự, đèn flash, cân bằng trắng và nhiều thứ nữa.

SubIFD chứa GPS

Chứa dữ liệu vị trí: vĩ độ, kinh độ, độ cao, thời điểm, số vệ tinh, tốc độ, hướng di chuyển. Rủi ro riêng tư lớn nhất.

Maker Notes

Dữ liệu riêng của từng hãng máy ảnh. Định dạng khác nhau tùy hãng. Có thể chứa số sê-ri, phiên bản firmware, các thiết lập tùy biến.

PicScrub xử lý TIFF như thế nào

1

Đọc header

Xác định thứ tự byte (II/MM) và tìm IFD đầu tiên

2

Lập danh sách thẻ được phép

Xác định những thẻ thiết yếu để hiển thị ảnh

3

Lọc các mục trong IFD

Xóa các thẻ siêu dữ liệu, đặt con trỏ SubIFD về 0

4

Ghi lại file

Dựng lại file TIFF với các IFD đã sạch và dữ liệu ảnh chép nguyên xi

Tính lại các offset

File TIFF dùng offset ở khắp nơi. Khi siêu dữ liệu bị xóa, PicScrub phải tính lại toàn bộ offset để file vẫn còn nguyên vẹn.