TIFF 파일 포맷 분석
* 특별한 언급이 없는 한 나오는 숫자는 모두 16진수로 간주함
TIF 파일의 물리적 데이터 배열
TIF 파일의 논리적 구성
Image File Header (IFH)
{
WORD Identifier; /* Byte-order Identifier */
WORD Version; /* TIFF version number (always 2Ah) */
DWORD IFDOffset; /* Offset of the first Image File Directory*/
} TIFHEAD;
헤더는 위와 같은 형태로 구성된다.
[Identifier] (2바이트)
Identifier가 49 49 (Little Endian) 혹은 4D 4D (Big Endian) 이면 TIFF 파일이다.
[Version] (2바이트)
Version 은 00 2A (Little Endian) 혹은 2A 00 (Big Endian).
[IFDOffset] (4바이트)
IFDOffset 은 첫 IFD의 오프셋이다. 만약 TIFF 파일 안에 페이지가 하나밖에 없다면 08 00 00 00 (Little Endian)일 확률이 높다.
* 어떤 파일의 HEX Data가 49 49 2A 00 (Little Endian) 이거나 4D 4D 00 2A (Big Endian) 이라면 TIFF 파일일 확률이 높다.
Image File Directory (IFD)
IFD의 포맷
IFD는 각 페이지의 헤더같은 존재임.
하지만 헤더처럼 일정한 위치와 형태를 지니지 않음.
하나의 TIFF 파일에는 최소한 1개 이상의 IFD가 존재함.
IFD
{
WORD NumDirEntries; /* Number of Tags in IFD */
TIFTAG TagList[]; /* Array of Tags */
DWORD NextIFDOffset; /* Offset to next IFD */
} TIFIFD;
[NumDirEntries] (2바이트)
IFD 에 태그가 몇개인지 나타냄.
예를 들어 NumDirEntries 값이 15 00 (Little Endian이므로 0x15) 이라면 21개의 태그가 있다는 뜻.
[TagList[]] (태그배열)
태그는 이미지 크기, 컬러, 압축 등의 정보를 가지고 있음.
각 태그는 12바이트의 크기를 지님.
[NextIFDOffset] (4바이트)
다음 IFD의 offset 정보.
만약 다음 IFD가 없다면 00 00 00 00 의 값을 가짐.
Tags
{
WORD TagId; /* The tag identifier */
WORD DataType; /* The scalar type of the data items */
DWORD DataCount; /* The number of items in the tag data */
DWORD DataOffset; /* The byte offset to the data items */
} TIFTAG;
[TagId] (2바이트)
태그 ID.
[DataType] (2바이트)
데이터 아이템의 타입
1 |
BYTE |
8-bit unsigned integer |
2 |
ASCII |
8-bit, NULL-terminated string |
3 |
SHORT |
16-bit unsigned integer |
4 |
LONG |
32-bit unsigned integer |
5 |
RATIONAL |
Two 32-bit unsigned integers |
6 |
SBYTE |
8-bit signed integer |
7 |
UNDEFINE |
8-bit byte |
8 |
SSHORT |
16-bit signed integer |
9 |
SLONG |
32-bit signed integer |
10 |
SRATIONAL |
Two 32-bit signed integers |
11 |
FLOAT |
4-byte single-precision IEEE floating-point value |
12 |
DOUBLE |
8-byte double-precision IEEE floating-point value |
[DataCount] (4바이트)
태그 데이터 안의 아이템 갯수
[DataOffset] (4바이트)
데이터 아이템의 byte offset
태그 종류 (Tag ID 는 십진수임)
Tag Name |
Tag ID |
Tag Type |
4.0 |
5.0 |
6.0 |
---|---|---|---|---|---|
Artist |
315 |
ASCII |
- |
* |
* |
BadFaxLines[1] |
326 |
SHORT or LONG |
- |
- |
- |
BitsPerSample |
258 |
SHORT |
* |
* |
* |
CellLength |
265 |
SHORT |
* |
* |
* |
CellWidth |
264 |
SHORT |
* |
* |
* |
CleanFaxData[1] |
327 |
SHORT |
- |
- |
- |
ColorMap |
320 |
SHORT |
- |
* |
* |
ColorResponseCurve |
301 |
SHORT |
* |
* |
x |
ColorResponseUnit |
300 |
SHORT |
* |
x |
x |
Compression |
259 |
SHORT |
* |
* |
* |
Uncompressed |
1 |
* |
* |
* | |
CCITT 1D |
2 |
* |
* |
* | |
CCITT Group 3 |
3 |
* |
* |
* | |
CCITT Group 4 |
4 |
* |
* |
* | |
LZW |
5 |
- |
* |
* | |
JPEG |
6 |
- |
- |
* | |
Uncompressed |
32771 |
* |
x |
x | |
Packbits |
32773 |
* |
* |
* | |
ConsecutiveBadFaxLines[1] |
328 |
LONG or SHORT |
- |
- |
- |
Copyright |
33432 |
ASCII |
- |
- |
* |
DateTime |
306 |
ASCII |
- |
* |
* |
DocumentName |
269 |
ASCII |
* |
* |
* |
DotRange |
336 |
BYTE or SHORT |
- |
- |
* |
ExtraSamples |
338 |
BYTE |
- |
- |
* |
FillOrder |
266 |
SHORT |
* |
* |
* |
FreeByteCounts |
289 |
LONG |
* |
* |
* |
FreeOffsets |
288 |
LONG |
* |
* |
* |
GrayResponseCurve |
291 |
SHORT |
* |
* |
* |
GrayResponseUnit |
290 |
SHORT |
* |
* |
* |
HalftoneHints |
321 |
SHORT |
- |
- |
* |
HostComputer |
316 |
ASCII |
- |
* |
* |
ImageDescription |
270 |
ASCII |
* |
* |
* |
ImageHeight |
257 |
SHORT or LONG |
* |
* |
* |
ImageWidth |
256 |
SHORT or LONG |
* |
* |
* |
InkNames |
333 |
ASCII |
- |
- |
* |
InkSet |
332 |
SHORT |
- |
- |
* |
JPEGACTTables |
521 |
LONG |
- |
- |
* |
JPEGDCTTables |
520 |
LONG |
- |
- |
* |
JPEGInterchangeFormat |
513 |
LONG |
- |
- |
* |
JPEGInterchangeFormatLength |
514 |
LONG |
- |
- |
* |
JPEGLosslessPredictors |
517 |
SHORT |
- |
- |
* |
JPEGPointTransforms |
518 |
SHORT |
- |
- |
* |
JPEGProc |
512 |
SHORT |
- |
- |
* |
JPEGRestartInterval |
515 |
SHORT |
- |
- |
* |
JPEGQTables |
519 |
LONG |
- |
- |
* |
Make |
271 |
ASCII |
* |
* |
* |
MaxSampleValue |
281 |
SHORT |
* |
* |
* |
MinSampleValue |
280 |
SHORT |
* |
* |
* |
Model |
272 |
ASCII |
* |
* |
* |
NewSubFileType |
254 |
LONG |
- |
* |
* |
NumberOfInks |
334 |
SHORT |
- |
- |
* |
Orientation |
274 |
SHORT |
* |
* |
* |
PageName |
285 |
ASCII |
* |
* |
* |
PageNumber |
297 |
SHORT |
* |
* |
* |
PhotometricInterpretation |
262 |
SHORT |
* |
* |
* |
WhiteIsZero |
0 |
* |
* |
* | |
BlackIsZero |
1 |
* |
* |
* | |
RGB |
2 |
* |
* |
* | |
RGB Palette |
3 |
- |
* |
* | |
Tranparency Mask |
4 |
- |
- |
* | |
CMYK |
5 |
- |
- |
* | |
YCbCr |
6 |
- |
- |
* | |
CIELab |
8 |
- |
- |
* | |
PlanarConfiguration |
284 |
SHORT |
* |
* |
* |
Predictor |
317 |
SHORT |
- |
* |
* |
PrimaryChromaticities |
319 |
RATIONAL |
- |
* |
* |
ReferenceBlackWhite |
532 |
LONG |
- |
- |
* |
ResolutionUnit |
296 |
SHORT |
* |
* |
* |
RowsPerStrip |
278 |
SHORT or LONG |
* |
* |
* |
SampleFormat |
339 |
SHORT |
- |
- |
* |
SamplesPerPixel |
277 |
SHORT |
* |
* |
* |
SMaxSampleValue |
341 |
Any |
- |
- |
* |
SMinSampleValue |
340 |
Any |
- |
- |
* |
Software |
305 |
ASCII |
- |
* |
* |
StripByteCounts |
279 |
LONG or SHORT |
* |
* |
* |
StripOffsets |
273 |
SHORT or LONG |
* |
* |
* |
SubFileType |
255 |
SHORT |
* |
x |
x |
T4Options[2] |
292 |
LONG |
* |
* |
* |
T6Options[3] |
293 |
LONG |
* |
* |
* |
TargetPrinter |
337 |
ASCII |
- |
- |
* |
Thresholding |
263 |
SHORT |
* |
* |
* |
TileByteCounts |
325 |
SHORT or LONG |
- |
- |
* |
TileLength |
323 |
SHORT or LONG |
- |
- |
* |
TileOffsets |
324 |
LONG |
- |
- |
* |
TileWidth |
322 |
SHORT or LONG |
- |
- |
* |
TransferFunction[4] |
301 |
SHORT |
- |
- |
* |
TransferRange |
342 |
SHORT |
- |
- |
* |
XPosition |
286 |
RATIONAL |
* |
* |
* |
XResolution |
282 |
RATIONAL |
* |
* |
* |
YCbCrCoefficients |
529 |
RATIONAL |
- |
- |
* |
YCbCrPositioning |
531 |
SHORT |
- |
- |
* |
YCbCrSubSampling |
530 |
SHORT |
- |
- |
* |
YPosition |
287 |
RATIONAL |
* |
* |
* |
YResolution |
283 |
RATIONAL |
* |
* |
* |
WhitePoint |
318 |
RATIONAL |
- |
* |
* |
Strips
TIFF 파일은 하나의 파일에 여러개의 이미지가 들어가야 하므로 Strip 이라는 개념이 있음. (TIFF 6.0 은 strips 보다 tiles 를 가지고 있을 확률이 높음)
strip은 비트맵 이미지 데이터의 연속적인 row의 모임.
(다른 이미지 포맷의 blocks, bands, chunks 같은 개념과 유사함)
strip 을 표현하기 위해 IFD에 3개의 Tag가 필요함. (RowsPerStrip, StripOffsets, StripByteCounts)
non-YCbCr subfile image 에서 strip의 수를 알려면 아래의 공식을 사용가능.
StripsInImage = floor((ImageLength * (RowsPerStrip - 1)) / RowsPerStrip);
Tiles
Strip이 Length만을 가진 1차원적인 오브젝트라면 Tile은 Width, Length를 가진 2차원적인 오브젝트.
수평적 strip으로 나누는 것보다 4각형 tile로 나누는 것이 고해상 이미지에서 훨씬 이익.
졸라 큰 이미지의 한쪽 귀퉁이만을 보여줄 때 strip을 사용하면 보이지 않는 나머지 면까지 압축을 풀고 메모리에 저장해야 하지만 tile로 할 경우엔 그렇지 않음. (딱 그 면 정도만 해주면 되니까)
Tiles로 구성된 TIFF 파일은 IFD에 RowsPerStrip, StripByteCounts, StripOffsets 태그 대신 TileWidth, TileLength, TileOffsets, TileByteCounts 태그가 필요함.
TileWidth, TileLength 는 항상 16의 배수여야 하고, 하나의 subfile 안에 있는 tile은 모두 같은 크기여야 함.
non-YCbCr subfile image 에서 타일의 수는 아래의 공식으로 구할 수 있음.
TilesAcross = (ImageWidth + (TileWidth + 1)) / TileWidth;
TilesDown = (ImageLength + (TileLength - 1)) / TileLength;
TilesInImage = TilesAcross * TilesDown;
이미지가 planes 로 나눠져 있을 경우(PlanarConfiguration = 2) 타일의 수는 아래의 공식으로 구함
TilesInImage = TilesAcross * TilesDown * SamplesPerPixel;
참고
http://netghost.narod.ru/gff/graphics/summary/tiff.htm
'컴퓨터관련 잡동사니' 카테고리의 다른 글
광마우스 분해법 (2) | 2009.06.21 |
---|---|
IE 소스보기 에디터 선택 (0) | 2009.06.19 |
팀 프로젝트 (0) | 2009.05.31 |
문자 인코딩 (0) | 2009.05.05 |
양아치 개발자를 알아보는 법 (0) | 2009.04.19 |