summaryrefslogtreecommitdiffstats
path: root/code/Common/IFF.h
blob: cdca13eb5a9a61b46869a6b69f140eb400ca4006 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Definitions for the Interchange File Format (IFF)
// Alexander Gessler, 2006
// Adapted to Assimp August 2008

#ifndef AI_IFF_H_INCLUDED
#define AI_IFF_H_INCLUDED

#include <assimp/ByteSwapper.h>

namespace Assimp {
namespace IFF {

/////////////////////////////////////////////////////////////////////////////////
//! Describes an IFF chunk header
/////////////////////////////////////////////////////////////////////////////////
struct ChunkHeader
{
    //! Type of the chunk header - FourCC
    uint32_t type;

    //! Length of the chunk data, in bytes
    uint32_t length;
};


/////////////////////////////////////////////////////////////////////////////////
//! Describes an IFF sub chunk header
/////////////////////////////////////////////////////////////////////////////////
struct SubChunkHeader
{
    //! Type of the chunk header - FourCC
    uint32_t type;

    //! Length of the chunk data, in bytes
    uint16_t length;
};

/////////////////////////////////////////////////////////////////////////////////
//! Describes an IFF form header
/////////////////////////////////////////////////////////////////////////////////
struct FormHeader
{
    //! Length of the chunk data, in bytes
    uint32_t length;

    //! Type of the chunk header - FourCC
    uint32_t type;
};

#define AI_IFF_FOURCC(a,b,c,d) ((uint32_t) (((uint8_t)a << 24u) | \
    ((uint8_t)b << 16u) | ((uint8_t)c << 8u) | ((uint8_t)d)))


#define AI_IFF_FOURCC_FORM AI_IFF_FOURCC('F','O','R','M')


/////////////////////////////////////////////////////////////////////////////////
//! Load a chunk header
//! @param outFile Pointer to the file data - points to the chunk data afterwards
//! @return Copy of the chunk header
/////////////////////////////////////////////////////////////////////////////////
inline ChunkHeader LoadChunk(uint8_t*& outFile)
{
    ChunkHeader head;
    ::memcpy(&head.type, outFile, 4);
    outFile += 4;
    ::memcpy(&head.length, outFile, 4);
    outFile += 4;
    AI_LSWAP4(head.length);
    AI_LSWAP4(head.type);
    return head;
}

/////////////////////////////////////////////////////////////////////////////////
//! Load a sub chunk header
//! @param outFile Pointer to the file data - points to the chunk data afterwards
//! @return Copy of the sub chunk header
/////////////////////////////////////////////////////////////////////////////////
inline SubChunkHeader LoadSubChunk(uint8_t*& outFile)
{
    SubChunkHeader head;
    ::memcpy(&head.type, outFile, 4);
    outFile += 4;
    ::memcpy(&head.length, outFile, 2);
    outFile += 2;
    AI_LSWAP2(head.length);
    AI_LSWAP4(head.type);
    return head;
}

/////////////////////////////////////////////////////////////////////////////////
//! Load a chunk header
//! @param outFile Pointer to the file data - points to the chunk data afterwards
//! @return Copy of the chunk header
/////////////////////////////////////////////////////////////////////////////////
inline ChunkHeader LoadForm(uint8_t*& outFile)
{
    ChunkHeader head;
    outFile += 4;
    ::memcpy(&head.length, outFile, 4);
    outFile += 4;
    ::memcpy(&head.type, outFile, 4);

    AI_LSWAP4(head.length);
    AI_LSWAP4(head.type);
    return head;
}

/////////////////////////////////////////////////////////////////////////////////
//! Read the file header and return the type of the file and its size
//! @param outFile Pointer to the file data. The buffer must at
//!   least be 12 bytes large.
//! @param fileType Receives the type of the file
//! @return 0 if everything was OK, otherwise an error message
/////////////////////////////////////////////////////////////////////////////////
inline const char* ReadHeader(uint8_t* outFile, uint32_t& fileType)
{
    ChunkHeader head = LoadChunk(outFile);
    if(AI_IFF_FOURCC_FORM != head.type)
    {
        return "The file is not an IFF file: FORM chunk is missing";
    }
    ::memcpy(&fileType, outFile, 4);
    AI_LSWAP4(fileType);
    return nullptr;
}


}}

#endif // !! AI_IFF_H_INCLUDED