kwave  18.07.70
Kwave::RIFFChunk Class Reference

#include <RIFFChunk.h>

Collaboration diagram for Kwave::RIFFChunk:
Collaboration graph

Public Types

enum  ChunkType {
  Root, Main, Sub, Garbage,
  Empty
}
 

Public Member Functions

 RIFFChunk (Kwave::RIFFChunk *parent, const QByteArray &name, const QByteArray &format, quint32 length, quint32 phys_offset, quint32 phys_length)
 
virtual ~RIFFChunk ()
 
bool isSane () const
 
ChunkType type () const
 
void setType (ChunkType type)
 
const QByteArray & name () const
 
const QByteArray & format () const
 
void setFormat (const QByteArray &format)
 
Kwave::RIFFChunkparent () const
 
const QByteArray path () const
 
quint32 dataStart () const
 
quint32 dataLength () const
 
quint32 length () const
 
void setLength (quint32 length)
 
quint32 physStart () const
 
quint32 physEnd () const
 
quint32 physLength () const
 
Kwave::RIFFChunkListsubChunks ()
 
const Kwave::RIFFChunkListsubChunks () const
 
bool isChildOf (Kwave::RIFFChunk *chunk)
 
void fixSize ()
 
void dumpStructure ()
 

Private Attributes

ChunkType m_type
 
QByteArray m_name
 
QByteArray m_format
 
Kwave::RIFFChunkm_parent
 
quint32 m_chunk_length
 
quint32 m_phys_offset
 
quint32 m_phys_length
 
Kwave::RIFFChunkList m_sub_chunks
 

Detailed Description

Stores information about a RIFF chunk, containing name, type, position in the source and length.

Definition at line 39 of file RIFFChunk.h.

Member Enumeration Documentation

◆ ChunkType

State of a chunk. Most are a sub-chunks. If one is known to contain further sub-chunks, it is marked as a main chunk. main and sub chunks always have a valid name and some length information, but might be truncated. If the name is not valid, the chunk is considered to contain only garbage. If the name is valid but there is no length information the chunk is marked as "empty".

Enumerator
Root 

virtual root node of the RIFF structure

Main 

contains sub-chunks

Sub 

valid/sane sub-chunk

Garbage 

no or invalid name

Empty 

valid name, but no size

Definition at line 50 of file RIFFChunk.h.

Constructor & Destructor Documentation

◆ RIFFChunk()

Kwave::RIFFChunk::RIFFChunk ( Kwave::RIFFChunk parent,
const QByteArray &  name,
const QByteArray &  format,
quint32  length,
quint32  phys_offset,
quint32  phys_length 
)

Constructor.

Parameters
parentpointer to the parent node (or null if root node)
namethe 4-byte name of the chunk
formatthe 4-byte format specifier, only valid for main chunks, contains invalid data in sub-chunks
lengthsize of the chunk's data
phys_offsetstart of the chunk name in the source
phys_lengthlength allocated in the source (file)

Definition at line 28 of file RIFFChunk.cpp.

31  :m_type(Sub), m_name(name), m_format(format), m_parent(parent),
32  m_chunk_length(length), m_phys_offset(phys_offset),
33  m_phys_length(phys_length), m_sub_chunks()
34 {
35 }
quint32 m_phys_offset
Definition: RIFFChunk.h:195
Kwave::RIFFChunkList m_sub_chunks
Definition: RIFFChunk.h:201
quint32 length() const
Definition: RIFFChunk.h:123
QByteArray m_format
Definition: RIFFChunk.h:186
ChunkType m_type
Definition: RIFFChunk.h:180
quint32 m_chunk_length
Definition: RIFFChunk.h:192
quint32 m_phys_length
Definition: RIFFChunk.h:198
Kwave::RIFFChunk * m_parent
Definition: RIFFChunk.h:189
QByteArray m_name
Definition: RIFFChunk.h:183
const QByteArray & name() const
Definition: RIFFChunk.h:91
const QByteArray & format() const
Definition: RIFFChunk.h:97

◆ ~RIFFChunk()

Kwave::RIFFChunk::~RIFFChunk ( )
virtual

Destructor

Definition at line 38 of file RIFFChunk.cpp.

References m_sub_chunks.

39 {
40  while (!m_sub_chunks.isEmpty()) {
41  Kwave::RIFFChunk *chunk = m_sub_chunks.takeLast();
42  if (chunk) delete chunk;
43  }
44 }
Kwave::RIFFChunkList m_sub_chunks
Definition: RIFFChunk.h:201

Member Function Documentation

◆ dataLength()

quint32 Kwave::RIFFChunk::dataLength ( ) const

Returns the physical length of the chunk's data

Definition at line 136 of file RIFFChunk.cpp.

References m_chunk_length, m_type, and Main.

Referenced by isSane(), Kwave::RIFFParser::joinGarbageToEmpty(), Kwave::WavDecoder::open(), parent(), Kwave::RIFFParser::parse(), and Kwave::WavDecoder::repairChunk().

137 {
138  return m_chunk_length - ((m_type == Main) ? 4 : 0);
139 }
ChunkType m_type
Definition: RIFFChunk.h:180
quint32 m_chunk_length
Definition: RIFFChunk.h:192
Here is the caller graph for this function:

◆ dataStart()

quint32 Kwave::RIFFChunk::dataStart ( ) const

Returns the offset where the chunk's data starts.

Definition at line 130 of file RIFFChunk.cpp.

References m_phys_offset, m_type, and Main.

Referenced by Kwave::RIFFParser::joinGarbageToEmpty(), Kwave::WavDecoder::open(), parent(), Kwave::RIFFParser::parse(), and Kwave::WavDecoder::repairChunk().

131 {
132  return m_phys_offset + ((m_type == Main) ? 12 : 8);
133 }
quint32 m_phys_offset
Definition: RIFFChunk.h:195
ChunkType m_type
Definition: RIFFChunk.h:180
Here is the caller graph for this function:

◆ dumpStructure()

void Kwave::RIFFChunk::dumpStructure ( )

Dumps the structure of this chunks and all sub-chunks, useful for debugging.

Definition at line 203 of file RIFFChunk.cpp.

References dumpStructure(), Empty, Garbage, length(), m_phys_offset, m_sub_chunks, m_type, Main, path(), physEnd(), physLength(), Root, and Sub.

Referenced by Kwave::RIFFParser::dumpStructure(), dumpStructure(), and subChunks().

204 {
205  // translate the type into a user-readable string
206  const char *t = "?unknown?";
207  switch (m_type) {
208  case Root: t = "ROOT"; break;
209  case Main: t = "MAIN"; break;
210  case Sub: t = "SUB"; break;
211  case Garbage: t = "GARBAGE"; break;
212  case Empty: t = "EMPTY"; break;
213  }
214 
215  // dump this chunk
216  qDebug("[0x%08X-0x%08X] (%10u/%10u) %7s, '%s'",
218  t, path().data()
219  );
220 
221  // recursively dump all sub-chunks
222  foreach (Kwave::RIFFChunk *chunk, m_sub_chunks)
223  if (chunk) chunk->dumpStructure();
224 
225 }
quint32 m_phys_offset
Definition: RIFFChunk.h:195
quint32 physEnd() const
Definition: RIFFChunk.cpp:79
Kwave::RIFFChunkList m_sub_chunks
Definition: RIFFChunk.h:201
quint32 physLength() const
Definition: RIFFChunk.h:146
quint32 length() const
Definition: RIFFChunk.h:123
const QByteArray path() const
Definition: RIFFChunk.cpp:88
ChunkType m_type
Definition: RIFFChunk.h:180
void dumpStructure()
Definition: RIFFChunk.cpp:203
Here is the call graph for this function:
Here is the caller graph for this function:

◆ fixSize()

void Kwave::RIFFChunk::fixSize ( )

Fixes descrepancies in the size of the chunk. The new size will be computed as the size of all sub-chunks (that will be recursively fixed too) plus the own header.

Definition at line 158 of file RIFFChunk.cpp.

References fixSize(), m_chunk_length, m_phys_length, m_type, Main, path(), physEnd(), physStart(), Root, and subChunks().

Referenced by fixSize(), Kwave::WavDecoder::repair(), and subChunks().

159 {
160  // pass one: fix sizes of sub chunks recursively
161  foreach (Kwave::RIFFChunk *chunk, subChunks())
162  if (chunk) chunk->fixSize();
163 
164  // pass two: sum up sub-chunks if type is main or root.
165  if ((m_type == Main) || (m_type == Root)) {
166  quint32 old_length = m_phys_length;
167  m_phys_length = 0;
168  if (m_type == Main) m_phys_length += 4;
169 
170  foreach (Kwave::RIFFChunk *chunk, subChunks()) {
171  if (!chunk) continue;
172  quint32 len = chunk->physEnd() - chunk->physStart() + 1;
173  m_phys_length += len;
174  }
175  if (m_phys_length != old_length) {
176  qDebug("%s: setting size from %u to %u",
177  path().data(), old_length, m_phys_length);
178  }
179  // chunk length is always equal to physical length for
180  // main and root !
182  } else {
183  // just round up if no main or root chunk
184  if (m_phys_length & 0x1) {
185  m_phys_length++;
186  qDebug("%s: rounding up size to %u", path().data(), m_phys_length);
187  }
188 
189  // adjust chunk size to physical size if not long enough
190  if ((m_chunk_length+1 != m_phys_length) &&
192  {
193  qDebug("%s: resizing chunk from %u to %u",
194  path().data(), m_chunk_length, m_phys_length);
196  }
197 
198  }
199 
200 }
quint32 physEnd() const
Definition: RIFFChunk.cpp:79
quint32 physStart() const
Definition: RIFFChunk.h:135
const QByteArray path() const
Definition: RIFFChunk.cpp:88
ChunkType m_type
Definition: RIFFChunk.h:180
quint32 m_chunk_length
Definition: RIFFChunk.h:192
quint32 m_phys_length
Definition: RIFFChunk.h:198
Kwave::RIFFChunkList & subChunks()
Definition: RIFFChunk.h:151
Here is the call graph for this function:
Here is the caller graph for this function:

◆ format()

const QByteArray& Kwave::RIFFChunk::format ( ) const
inline

Returns the chunk's format string.

Note
Only valid for main chunk

Definition at line 97 of file RIFFChunk.h.

References m_format.

Referenced by path(), Kwave::WavDecoder::repairChunk(), and setFormat().

97 { return m_format; }
QByteArray m_format
Definition: RIFFChunk.h:186
Here is the caller graph for this function:

◆ isChildOf()

bool Kwave::RIFFChunk::isChildOf ( Kwave::RIFFChunk chunk)

Returns true if the given chunk is a parent of us.

Definition at line 149 of file RIFFChunk.cpp.

References isChildOf(), m_parent, m_type, and Root.

Referenced by Kwave::RIFFParser::fixGarbageEnds(), isChildOf(), and subChunks().

150 {
151  if (!chunk) return (m_type == Root); // only root has null as parent
152  if (chunk == m_parent) return true;
153  if (m_parent) return m_parent->isChildOf(chunk);
154  return false;
155 }
ChunkType m_type
Definition: RIFFChunk.h:180
bool isChildOf(Kwave::RIFFChunk *chunk)
Definition: RIFFChunk.cpp:149
Kwave::RIFFChunk * m_parent
Definition: RIFFChunk.h:189
Here is the call graph for this function:
Here is the caller graph for this function:

◆ isSane()

bool Kwave::RIFFChunk::isSane ( ) const

Returns true if the file chunk no structural errors and no garbage or empty chunks.

Definition at line 49 of file RIFFChunk.cpp.

References CHECK, dataLength(), Empty, Garbage, isSane(), m_phys_length, m_sub_chunks, m_type, Main, path(), Root, and subChunks().

Referenced by Kwave::RIFFParser::isSane(), and isSane().

50 {
51  CHECK(m_type == Empty);
52  CHECK(m_type == Garbage);
53  CHECK((m_type == Main) && m_sub_chunks.isEmpty());
54  CHECK((m_type == Root) && m_sub_chunks.isEmpty());
55 
56 #ifdef DEBUG
57  if (m_phys_length & 0x1) {
58  // size is not an even number: no criterium for insanity
59  // but worth a warning
60  qWarning("%s: physical length is not an even number: %u",
61  path().data(), m_phys_length);
62  }
63 #endif /* DEBUG */
64 
65  unsigned int datalen = dataLength();
66  if (m_type == Main) datalen += 4;
67  if (((datalen + 1) < m_phys_length) || (datalen > m_phys_length)) {
68  qWarning("%s: dataLength=%u, phys_length=%u",
69  path().data(), datalen, m_phys_length);
70  return false;
71  }
72 
73  foreach (const Kwave::RIFFChunk *chunk, subChunks())
74  if (chunk && !chunk->isSane()) return false;
75  return true;
76 }
Kwave::RIFFChunkList m_sub_chunks
Definition: RIFFChunk.h:201
#define CHECK(x)
Definition: RIFFChunk.cpp:48
const QByteArray path() const
Definition: RIFFChunk.cpp:88
ChunkType m_type
Definition: RIFFChunk.h:180
quint32 dataLength() const
Definition: RIFFChunk.cpp:136
quint32 m_phys_length
Definition: RIFFChunk.h:198
Kwave::RIFFChunkList & subChunks()
Definition: RIFFChunk.h:151
bool isSane() const
Definition: RIFFChunk.cpp:49
Here is the call graph for this function:
Here is the caller graph for this function:

◆ length()

quint32 Kwave::RIFFChunk::length ( ) const
inline

Returns the length of the chunk in bytes, like stated in the head of the chunk. Includes the format when it's a main chunk.

Definition at line 123 of file RIFFChunk.h.

References m_chunk_length, and setLength().

Referenced by dumpStructure(), Kwave::WavDecoder::open(), and setLength().

123 { return m_chunk_length; }
quint32 m_chunk_length
Definition: RIFFChunk.h:192
Here is the call graph for this function:
Here is the caller graph for this function:

◆ name()

const QByteArray& Kwave::RIFFChunk::name ( ) const
inline

Returns the 4-character name of the chunk

Definition at line 91 of file RIFFChunk.h.

References m_name.

Referenced by Kwave::RIFFParser::chunkCount(), Kwave::RIFFParser::findChunk(), Kwave::RIFFParser::fixGarbageEnds(), Kwave::RIFFParser::joinGarbageToEmpty(), Kwave::WavDecoder::open(), Kwave::RIFFParser::parse(), path(), Kwave::WavDecoder::repair(), and Kwave::WavDecoder::repairChunk().

91 { return m_name; }
QByteArray m_name
Definition: RIFFChunk.h:183
Here is the caller graph for this function:

◆ parent()

Kwave::RIFFChunk* Kwave::RIFFChunk::parent ( ) const
inline

Returns the pointer to the parent node

Definition at line 103 of file RIFFChunk.h.

References dataLength(), dataStart(), m_parent, and path().

Referenced by Kwave::RIFFParser::addChunk(), and Kwave::RIFFParser::joinGarbageToEmpty().

103 { return m_parent; }
Kwave::RIFFChunk * m_parent
Definition: RIFFChunk.h:189
Here is the call graph for this function:
Here is the caller graph for this function:

◆ path()

const QByteArray Kwave::RIFFChunk::path ( ) const

Returns the full path of this node. If the node is a "Main" chunk and has a format parameter, the format is appended, separated with a ":". If the chunk name is not unique within it's parents the zero based index is appended within round brackets.

Definition at line 88 of file RIFFChunk.cpp.

References format(), m_format, m_name, m_parent, m_type, Main, name(), path(), subChunks(), and type().

Referenced by Kwave::RIFFParser::chunkCount(), dumpStructure(), Kwave::RIFFParser::findChunk(), fixSize(), isSane(), parent(), Kwave::RIFFParser::parse(), and path().

89 {
90  QByteArray p = "";
91 
92  if (m_parent) p += m_parent->path() + '/';
93  p += m_name;
94  if (m_type == Main) p += ':' + m_format;
95 
96  if (m_parent) {
97  QListIterator<Kwave::RIFFChunk *> it(m_parent->subChunks());
98  unsigned int before = 0;
99  unsigned int after = 0;
100  const Kwave::RIFFChunk *chunk = Q_NULLPTR;
101  while (it.hasNext()) {
102  chunk = it.next();
103  if (!chunk) continue;
104  if (chunk == this) break;
105  if (chunk->name() != m_name) continue;
106  if (chunk->type() != m_type) continue;
107  if ((m_type == Main) && (chunk->format() != m_format)) continue;
108  before++;
109  }
110  if ((chunk == this) && (it.hasNext())) chunk = it.next();
111  while ((chunk != this) && (it.hasNext())) {
112  chunk = it.next();
113  if (!chunk) continue;
114  if (chunk->name() != m_name) continue;
115  if (chunk->type() != m_type) continue;
116  if ((m_type == Main) && (chunk->format() != m_format)) continue;
117  after++;
118  }
119  if (before + after != 0) {
120  QByteArray index;
121  index.setNum(before);
122  p += '(' + index + ')';
123  }
124  }
125 
126  return p;
127 }
QByteArray m_format
Definition: RIFFChunk.h:186
const QByteArray path() const
Definition: RIFFChunk.cpp:88
ChunkType type() const
Definition: RIFFChunk.h:85
ChunkType m_type
Definition: RIFFChunk.h:180
Kwave::RIFFChunkList & subChunks()
Definition: RIFFChunk.h:151
Kwave::RIFFChunk * m_parent
Definition: RIFFChunk.h:189
QByteArray m_name
Definition: RIFFChunk.h:183
const QByteArray & name() const
Definition: RIFFChunk.h:91
const QByteArray & format() const
Definition: RIFFChunk.h:97
Here is the call graph for this function:
Here is the caller graph for this function:

◆ physEnd()

quint32 Kwave::RIFFChunk::physEnd ( ) const

Returns the offset in the source (file) where the chunk ends.

Definition at line 79 of file RIFFChunk.cpp.

References Garbage, m_phys_length, m_phys_offset, m_type, and Root.

Referenced by Kwave::RIFFParser::collectGarbage(), dumpStructure(), Kwave::RIFFParser::findMissingChunk(), Kwave::RIFFParser::fixGarbageEnds(), fixSize(), Kwave::RIFFParser::parse(), and physStart().

80 {
81  quint32 end = m_phys_offset + m_phys_length;
82  if (m_phys_length) --end;
83  if ((m_type != Root) && (m_type != Garbage)) end += 8;
84  return end;
85 }
quint32 m_phys_offset
Definition: RIFFChunk.h:195
ChunkType m_type
Definition: RIFFChunk.h:180
quint32 m_phys_length
Definition: RIFFChunk.h:198
Here is the caller graph for this function:

◆ physLength()

quint32 Kwave::RIFFChunk::physLength ( ) const
inline

Returns the length of the chunk in the file. For some dubious reason this seems always to be rounded up for even numbers!

Definition at line 146 of file RIFFChunk.h.

References m_phys_length.

Referenced by Kwave::RIFFParser::detectEndianness(), dumpStructure(), Kwave::RIFFParser::findMissingChunk(), Kwave::RIFFParser::joinGarbageToEmpty(), Kwave::WavDecoder::open(), Kwave::RIFFParser::parse(), Kwave::WavDecoder::repair(), and Kwave::WavDecoder::repairChunk().

146 { return m_phys_length; }
quint32 m_phys_length
Definition: RIFFChunk.h:198
Here is the caller graph for this function:

◆ physStart()

quint32 Kwave::RIFFChunk::physStart ( ) const
inline

Returns the offset in the source (file) where the chunk (name) starts.

Definition at line 135 of file RIFFChunk.h.

References m_phys_offset, and physEnd().

Referenced by Kwave::RIFFParser::addChunk(), Kwave::RIFFParser::chunkAt(), Kwave::RIFFParser::collectGarbage(), Kwave::RIFFParser::detectEndianness(), Kwave::RIFFParser::findMissingChunk(), Kwave::RIFFParser::fixGarbageEnds(), fixSize(), Kwave::RIFFParser::joinGarbageToEmpty(), and Kwave::WavDecoder::repair().

135 { return m_phys_offset; }
quint32 m_phys_offset
Definition: RIFFChunk.h:195
Here is the call graph for this function:
Here is the caller graph for this function:

◆ setFormat()

void Kwave::RIFFChunk::setFormat ( const QByteArray &  format)
inline

Sets the format to a new value, without any error checking

Definition at line 100 of file RIFFChunk.h.

References format(), and m_format.

Referenced by Kwave::RIFFParser::joinGarbageToEmpty().

100 { m_format = format; }
QByteArray m_format
Definition: RIFFChunk.h:186
const QByteArray & format() const
Definition: RIFFChunk.h:97
Here is the call graph for this function:
Here is the caller graph for this function:

◆ setLength()

void Kwave::RIFFChunk::setLength ( quint32  length)

Sets the data and physical length of the chunk both to a new value.

Definition at line 142 of file RIFFChunk.cpp.

References length(), m_chunk_length, and m_phys_length.

Referenced by Kwave::RIFFParser::collectGarbage(), Kwave::RIFFParser::fixGarbageEnds(), Kwave::RIFFParser::joinGarbageToEmpty(), and length().

143 {
146 }
quint32 length() const
Definition: RIFFChunk.h:123
quint32 m_chunk_length
Definition: RIFFChunk.h:192
quint32 m_phys_length
Definition: RIFFChunk.h:198
Here is the call graph for this function:
Here is the caller graph for this function:

◆ setType()

void Kwave::RIFFChunk::setType ( ChunkType  type)
inline

Sets the type of the chunk

Definition at line 88 of file RIFFChunk.h.

References m_type, and type().

Referenced by Kwave::RIFFParser::addChunk(), Kwave::RIFFParser::collectGarbage(), Kwave::RIFFParser::joinGarbageToEmpty(), Kwave::RIFFParser::parse(), Kwave::WavDecoder::repair(), and Kwave::RIFFParser::RIFFParser().

88 { m_type = type; }
ChunkType type() const
Definition: RIFFChunk.h:85
ChunkType m_type
Definition: RIFFChunk.h:180
Here is the call graph for this function:
Here is the caller graph for this function:

◆ subChunks() [1/2]

Kwave::RIFFChunkList& Kwave::RIFFChunk::subChunks ( )
inline

◆ subChunks() [2/2]

const Kwave::RIFFChunkList& Kwave::RIFFChunk::subChunks ( ) const
inline

Returns a reference to the list of sub-chunks (const).

Definition at line 156 of file RIFFChunk.h.

References dumpStructure(), fixSize(), isChildOf(), and m_sub_chunks.

156  {
157  return m_sub_chunks;
158  }
Kwave::RIFFChunkList m_sub_chunks
Definition: RIFFChunk.h:201
Here is the call graph for this function:

◆ type()

ChunkType Kwave::RIFFChunk::type ( ) const
inline

Member Data Documentation

◆ m_chunk_length

quint32 Kwave::RIFFChunk::m_chunk_length
private

length of the chunk

Definition at line 192 of file RIFFChunk.h.

Referenced by dataLength(), fixSize(), length(), and setLength().

◆ m_format

QByteArray Kwave::RIFFChunk::m_format
private

format of the chunk, only valid for main chunks

Definition at line 186 of file RIFFChunk.h.

Referenced by format(), path(), and setFormat().

◆ m_name

QByteArray Kwave::RIFFChunk::m_name
private

chunk name, always 4 bytes ASCII

Definition at line 183 of file RIFFChunk.h.

Referenced by name(), and path().

◆ m_parent

Kwave::RIFFChunk* Kwave::RIFFChunk::m_parent
private

path of the parent chunk

Definition at line 189 of file RIFFChunk.h.

Referenced by isChildOf(), parent(), and path().

◆ m_phys_length

quint32 Kwave::RIFFChunk::m_phys_length
private

length used in the source (file)

Definition at line 198 of file RIFFChunk.h.

Referenced by fixSize(), isSane(), physEnd(), physLength(), and setLength().

◆ m_phys_offset

quint32 Kwave::RIFFChunk::m_phys_offset
private

offset within the source (file)

Definition at line 195 of file RIFFChunk.h.

Referenced by dataStart(), dumpStructure(), physEnd(), and physStart().

◆ m_sub_chunks

Kwave::RIFFChunkList Kwave::RIFFChunk::m_sub_chunks
private

list of sub-chunks, empty if none known

Definition at line 201 of file RIFFChunk.h.

Referenced by dumpStructure(), isSane(), subChunks(), and ~RIFFChunk().

◆ m_type

ChunkType Kwave::RIFFChunk::m_type
private

type of this chunk: main or sub chunk

Definition at line 180 of file RIFFChunk.h.

Referenced by dataLength(), dataStart(), dumpStructure(), fixSize(), isChildOf(), isSane(), path(), physEnd(), setType(), and type().


The documentation for this class was generated from the following files: