1 // This file is part of the interchange file format library.
3 // Copyright (C) 2003-2006 by Mike Sharov <msharov@users.sourceforge.net>
4 // This file is free software, distributed under the MIT License.
8 // Chunk header formats for the Interchange File Format.
11 #ifndef HEADS_H_6AE64E742217B13E3F576C6D5A4C3292
12 #define HEADS_H_6AE64E742217B13E3F576C6D5A4C3292
16 /// Contains functions for dealing with IFF formatted files.
20 //----------------------------------------------------------------------
22 //----------------------------------------------------------------------
23 typedef uint32_t fmt_t
; ///< Type for format fields in the headers
24 typedef uint32_t chsize_t
; ///< Type for the chunk size field
25 typedef uint32_t ccount_t
; ///< Type for the child count field
27 //----------------------------------------------------------------------
28 // IFF standard chunk formats
29 //----------------------------------------------------------------------
31 #if IFF_BYTE_ORDER == USTL_LITTLE_ENDIAN
32 #define IFF_FMT(a,b,c,d) ((((((::iff::fmt_t(d)<<8)|(c))<<8)|(b))<<8)|(a))
33 inline void boci2n (uint32_t& v
) { v
= le_to_native(v
); }
34 inline uint32_t bon2i(uint32_t v
) { return (native_to_le(v
)); }
36 #define IFF_FMT(a,b,c,d) ((((((::iff::fmt_t(a)<<8)|(b))<<8)|(c))<<8)|(d))
37 inline void boci2n (uint32_t& v
) { v
= be_to_native(v
); }
38 inline uint32_t bon2i(uint32_t v
) { return (native_to_be(v
)); }
40 #define IFF_SFMT(s) IFF_FMT(s[0],s[1],s[2],s[3])
44 cfmt_FORM
= IFF_FMT('F','O','R','M'),
45 cfmt_LIST
= IFF_FMT('L','I','S','T'),
46 cfmt_CAT
= IFF_FMT('C','A','T',' '),
47 cfmt_Filler
= IFF_FMT(' ',' ',' ',' '),
48 cfmt_Bitmap
= IFF_FMT('I','L','B','M'),
49 cfmt_Properties
= IFF_FMT('P','R','O','P'),
50 cfmt_BitmapHeader
= IFF_FMT('B','M','H','D'),
51 cfmt_ColorMap
= IFF_FMT('C','M','A','P'),
52 cfmt_ColorLookupTable
= IFF_FMT('C','L','U','T'),
53 cfmt_ColorCycle1
= IFF_FMT('C','R','N','G'),
54 cfmt_ColorCycle2
= IFF_FMT('C','C','R','T'),
55 cfmt_HotSpot
= IFF_FMT('G','R','A','B'),
56 cfmt_Sprite
= IFF_FMT('S','P','R','T'),
57 cfmt_VoiceHeader
= IFF_FMT('V','H','D','R'),
58 cfmt_Name
= IFF_FMT('N','A','M','E'),
59 cfmt_Copyright
= IFF_FMT('(','c',')',' '),
60 cfmt_Author
= IFF_FMT('A','U','T','H'),
61 cfmt_Annotation
= IFF_FMT('A','N','N','O'),
62 cfmt_Attack
= IFF_FMT('A','T','A','K'),
63 cfmt_Release
= IFF_FMT('R','L','S','E'),
64 cfmt_Generic
= IFF_FMT('B','O','D','Y'),
65 cfmt_Vector
= IFF_FMT('V','E','C','T'),
66 cfmt_CountedContainer
= IFF_FMT('C','N','T','R'),
67 cfmt_StringTable
= IFF_FMT('S','T','R','T'),
68 cfmt_Autodetect
= IFF_FMT('A','U','T','O')
71 //----------------------------------------------------------------------
73 /// \class CChunkHeader heads.h iff.h
75 /// \brief Header for non-aggregate chunks.
77 /// Contains size and format information for the chunk. Like
78 /// CContainerHeader, the written format is the spec too, so
79 /// can be written manually. The size is the size of the
80 /// chunk data, not including the header
84 inline CChunkHeader (void) : m_Format (cfmt_Generic
), m_Size (0) { }
85 inline CChunkHeader (chsize_t size
, fmt_t fmt
= cfmt_Generic
) : m_Format (fmt
), m_Size (size
) { }
86 inline void read (istream
& is
) { is
>> m_Format
>> m_Size
; boci2n(m_Format
); boci2n(m_Size
); }
87 inline void write (ostream
& os
) const { os
<< bon2i(m_Format
) << bon2i(m_Size
); }
88 inline size_t stream_size (void) const { return (stream_size_of(m_Format
) + stream_size_of(m_Size
)); }
89 inline size_t Size (void) const { return (m_Size
); }
90 inline size_t SizeWithHeader (void) const { return (Size() + stream_size()); }
91 inline fmt_t
Format (void) const { return (m_Format
); }
92 void Verify (fmt_t fmt
= cfmt_Generic
, const char* chunkName
= "chunk", uoff_t offset
= 0) const;
94 fmt_t m_Format
; ///< Format of the chunk
95 chsize_t m_Size
; ///< Size of the chunk including the header.
98 //----------------------------------------------------------------------
100 /// \class CGroupHeader heads.h iff.h
102 /// \brief Header for aggregate chunks like FORM, LIST, and CAT
103 /// This header can be written standalone, or with WriteVector.
104 /// Each IFF file must start with a group header with file size
105 /// and type of contents.
107 class CGroupHeader
: public CChunkHeader
{
110 CGroupHeader (chsize_t size
, fmt_t childFormat
= cfmt_Generic
, fmt_t fmt
= cfmt_FORM
);
111 inline void read (istream
& is
) { CChunkHeader::read (is
); is
>> m_ChildFormat
; boci2n (m_ChildFormat
); }
112 inline void write (ostream
& os
) const { CChunkHeader::write (os
); os
<< bon2i(m_ChildFormat
); }
113 inline size_t stream_size (void) const { return (CChunkHeader::stream_size() + stream_size_of(m_ChildFormat
)); }
114 inline fmt_t
ChildFormat (void) const { return (m_ChildFormat
); }
115 inline size_t Size (void) const { return (CChunkHeader::Size() - (stream_size() - CChunkHeader::stream_size())); }
116 void Verify (fmt_t childFormat
= cfmt_Generic
, fmt_t fmt
= cfmt_FORM
, const char* chunkName
= "FORM", uoff_t offset
= 0) const;
118 fmt_t m_ChildFormat
; ///< Format of each child chunk.
121 //----------------------------------------------------------------------
123 /// \brief PROP section values
125 fmt_t m_Name
; ///< 4 character prop name (use IFF_FMT to define)
126 uint32_t m_Value
; ///< Property value.
129 //----------------------------------------------------------------------
133 ALIGNOF(iff::CChunkHeader
, IFF_GRAIN
)
134 STD_STREAMABLE(iff::CChunkHeader
)
135 STD_STREAMABLE(iff::CGroupHeader
)