Tag Parser  6.4.1
C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags
oggpage.cpp
Go to the documentation of this file.
1 #include "./oggpage.h"
2 
3 #include "../exceptions.h"
4 
5 #include <c++utilities/io/binaryreader.h>
6 #include <c++utilities/conversion/binaryconversion.h>
7 
8 using namespace std;
9 using namespace IoUtilities;
10 using namespace ConversionUtilities;
11 
12 namespace Media {
13 
25 void OggPage::parseHeader(istream &stream, uint64 startOffset, int32 maxSize)
26 {
27  // prepare reading
28  stream.seekg(startOffset);
29  BinaryReader reader(&stream);
30  if(maxSize < 27) {
31  throw TruncatedDataException();
32  } else {
33  maxSize -= 27;
34  }
35  // read header values
36  if(reader.readUInt32LE() != 0x5367674f) {
37  throw InvalidDataException();
38  }
39  m_startOffset = startOffset;
40  m_streamStructureVersion = reader.readByte();
41  m_headerTypeFlag = reader.readByte();
42  m_absoluteGranulePosition = reader.readUInt64LE();
43  m_streamSerialNumber = reader.readUInt32LE();
44  m_sequenceNumber = reader.readUInt32LE();
45  m_checksum = reader.readUInt32LE();
46  m_segmentCount = reader.readByte();
47  m_segmentSizes.clear();
48  if(m_segmentCount > 0) {
49  if(maxSize < m_segmentCount) {
50  throw TruncatedDataException();
51  } else {
52  maxSize -= m_segmentCount;
53  }
54  // read segment size tabe
55  m_segmentSizes.push_back(0);
56  for(byte i = 0; i < m_segmentCount;) {
57  byte entry = reader.readByte();
58  maxSize -= entry;
59  m_segmentSizes.back() += entry;
60  if(++i < m_segmentCount && entry < 0xff) {
61  m_segmentSizes.push_back(0);
62  }
63  }
64  // check whether the maximum size is exceeded
65  if(maxSize < 0) {
66  throw TruncatedDataException();
67  }
68  }
69 }
70 
75 uint32 OggPage::computeChecksum(istream &stream, uint64 startOffset)
76 {
77  stream.seekg(startOffset);
78  uint32 crc = 0x0;
79  byte value, segmentTableSize = 0, segmentTableIndex = 0;
80  for(uint32 i = 0, segmentLength = 27; i != segmentLength; ++i) {
81  switch(i) {
82  case 22:
83  // bytes 22, 23, 24, 25 hold denoted checksum and must be set to zero
84  stream.seekg(4, ios_base::cur);
85  case 23: case 24: case 25:
86  value = 0;
87  break;
88  case 26:
89  // byte 26 holds the number of segment sizes
90  segmentLength += (segmentTableSize = (value = stream.get()));
91  break;
92  default:
93  value = stream.get();
94  if(i > 26 && segmentTableIndex < segmentTableSize) {
95  // bytes 27 to (27 + segment size count) hold page size
96  segmentLength += value;
97  ++segmentTableIndex;
98  }
99  }
100  crc = (crc << 8) ^ BinaryReader::crc32Table[((crc >> 24) & 0xFF) ^ value];
101  }
102  return crc;
103 }
104 
109 void OggPage::updateChecksum(iostream &stream, uint64 startOffset)
110 {
111  char buff[4];
112  LE::getBytes(computeChecksum(stream, startOffset), buff);
113  stream.seekp(startOffset + 22);
114  stream.write(buff, sizeof(buff));
115 }
116 
121 uint32 OggPage::makeSegmentSizeDenotation(ostream &stream, uint32 size)
122 {
123  uint32 bytesWritten = 1;
124  while(size >= 0xff) {
125  stream.put(0xff);
126  size -= 0xff;
127  ++bytesWritten;
128  }
129  stream.put(size);
130  return bytesWritten;
131 }
132 
133 }
STL namespace.
Contains utility classes helping to read and write streams.
The exception that is thrown when the data to be parsed or to be made seems invalid and therefore can...
Definition: exceptions.h:27
The exception that is thrown when the data to be parsed is truncated and therefore can not be parsed ...
Definition: exceptions.h:35
Contains all classes and functions of the TagInfo library.
Definition: exceptions.h:9