TIFF 파일 포맷 분석
* 특별한 언급이 없는 한 나오는 숫자는 모두 16진수로 간주함




TIF 파일의 물리적 데이터 배열










TIF 파일의 논리적 구성










Image File Header (IFH)

typedef struct _TiffHeader
{
    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

typedef struct _TifIfd
{
    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

typedef struct _TifTag
{
    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
Posted by bloodguy
,