1 /*************************************************************************
2             RIFFChunk.h  -  information about a RIFF chunk
3                              -------------------
4     begin                : Tue Mar 20 2002
5     copyright            : (C) 2002 by Thomas Eschenbacher
6     email                : Thomas.Eschenbacher@gmx.de
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 
18 #ifndef RIFF_CHUNK_H
19 #define RIFF_CHUNK_H
20 
21 #include "config.h"
22 
23 #include <QByteArray>
24 #include <QList>
25 #include <QString>
26 
27 namespace Kwave
28 {
29 
30     class RIFFChunk;
31 
32     /** shortcut for list of RIFF chunks */
33     typedef QList<Kwave::RIFFChunk *> RIFFChunkList;
34 
35     /**
36      * Stores information about a RIFF chunk, containing name, type, position
37      * in the source and length.
38      */
39     class RIFFChunk
40     {
41     public:
42 	/**
43 	 * State of a chunk. Most are a sub-chunks. If one is known to contain
44 	 * further sub-chunks, it is marked as a main chunk. main and sub chunks
45 	 * always have a valid name and some length information, but might be
46 	 * truncated. If the name is not valid, the chunk is considered to
47 	 * contain only garbage. If the name is valid but there is no length
48 	 * information the chunk is marked as "empty".
49 	 */
50 	typedef enum {
51 	    Root,    /**< virtual root node of the RIFF structure */
52 	    Main,    /**< contains sub-chunks */
53 	    Sub,     /**< valid/sane sub-chunk */
54 	    Garbage, /**< no or invalid name */
55 	    Empty    /**< valid name, but no size */
56 	} ChunkType;
57 
58 	/**
59 	 * Constructor.
60 	 * @param parent pointer to the parent node (or null if root node)
61 	 * @param name the 4-byte name of the chunk
62 	 * @param format the 4-byte format specifier, only valid for
63 	 *               main chunks, contains invalid data in sub-chunks
64 	 * @param length size of the chunk's data
65 	 * @param phys_offset start of the chunk name in the source
66 	 * @param phys_length length allocated in the source (file)
67 	 */
68 	RIFFChunk(Kwave::RIFFChunk *parent, const QByteArray &name,
69 	          const QByteArray &format, quint32 length,
70 	          quint32 phys_offset, quint32 phys_length);
71 
72 	/** Destructor */
73 	virtual ~RIFFChunk();
74 
75 	/**
76 	 * Returns true if the file chunk no structural errors and
77 	 * no garbage or empty chunks.
78 	 */
79 	bool isSane() const;
80 
81 	/**
82 	 * Returns the type of the chunk.
83 	 * @see ChunkType
84 	 */
type()85 	inline ChunkType type() const { return m_type; }
86 
87 	/** Sets the type of the chunk */
setType(ChunkType type)88 	inline void setType(ChunkType type) { m_type = type; }
89 
90 	/** Returns the 4-character name of the chunk */
name()91 	inline const QByteArray &name() const { return m_name; }
92 
93 	/**
94 	 * Returns the chunk's format string.
95 	 * @note Only valid for main chunk
96 	 */
format()97 	inline const QByteArray &format() const { return m_format; }
98 
99 	/** Sets the format to a new value, without any error checking */
setFormat(const QByteArray & format)100 	inline void setFormat(const QByteArray &format) { m_format = format; }
101 
102 	/** Returns the pointer to the parent node */
parent()103 	inline Kwave::RIFFChunk *parent() const { return m_parent; }
104 
105 	/**
106 	 * Returns the full path of this node. If the node is a "Main" chunk
107 	 * and has a format parameter, the format is appended, separated with
108 	 * a ":". If the chunk name is not unique within it's parents the
109 	 * zero based index is appended within round brackets.
110 	 */
111 	const QByteArray path() const;
112 
113 	/** Returns the offset where the chunk's data starts. */
114 	quint32 dataStart() const;
115 
116 	/** Returns the physical length of the chunk's data */
117 	quint32 dataLength() const;
118 
119 	/**
120 	 * Returns the length of the chunk in bytes, like stated in the
121 	 * head of the chunk. Includes the format when it's a main chunk.
122 	 */
length()123 	inline quint32 length() const { return m_chunk_length; }
124 
125 	/**
126 	 * Sets the data and physical length of the chunk both to a
127 	 * new value.
128 	 */
129 	void setLength(quint32 length);
130 
131 	/**
132 	 * Returns the offset in the source (file) where the
133 	 * chunk (name) starts.
134 	 */
physStart()135 	inline quint32 physStart() const { return m_phys_offset; }
136 
137 	/**
138 	 * Returns the offset in the source (file) where the chunk ends.
139 	 */
140 	quint32 physEnd() const;
141 
142 	/**
143 	 * Returns the length of the chunk in the file. For some dubious
144 	 * reason this seems always to be rounded up for even numbers!
145 	 */
physLength()146 	inline quint32 physLength() const { return m_phys_length; }
147 
148 	/**
149 	 * Returns a reference to the list of sub-chunks (mutable).
150 	 */
subChunks()151 	inline Kwave::RIFFChunkList &subChunks() { return m_sub_chunks; }
152 
153 	/**
154 	 * Returns a reference to the list of sub-chunks (const).
155 	 */
subChunks()156 	inline const Kwave::RIFFChunkList &subChunks() const {
157 	    return m_sub_chunks;
158 	}
159 
160 	/**
161 	 * Returns true if the given chunk is a parent of us.
162 	 */
163 	bool isChildOf(Kwave::RIFFChunk *chunk);
164 
165 	/**
166 	 * Fixes descrepancies in the size of the chunk. The new size will be
167 	 * computed as the size of all sub-chunks (that will be recursively
168 	 * fixed too) plus the own header.
169 	 */
170 	void fixSize();
171 
172 	/**
173 	 * Dumps the structure of this chunks and all sub-chunks,
174 	 * useful for debugging.
175 	 */
176 	void dumpStructure();
177 
178     private:
179 	/** type of this chunk: main or sub chunk */
180 	ChunkType m_type;
181 
182 	/** chunk name, always 4 bytes ASCII */
183 	QByteArray m_name;
184 
185 	/** format of the chunk, only valid for main chunks */
186 	QByteArray m_format;
187 
188 	/** path of the parent chunk */
189 	Kwave::RIFFChunk *m_parent;
190 
191 	/** length of the chunk */
192 	quint32 m_chunk_length;
193 
194 	/** offset within the source (file) */
195 	quint32 m_phys_offset;
196 
197 	/** length used in the source (file) */
198 	quint32 m_phys_length;
199 
200 	/** list of sub-chunks, empty if none known */
201 	Kwave::RIFFChunkList m_sub_chunks;
202 
203     };
204 }
205 
206 #endif /* RIFF_CHUNK_H */
207 
208 //***************************************************************************
209 //***************************************************************************
210