-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathID3V2Tag.cpp
More file actions
79 lines (61 loc) · 2.27 KB
/
ID3V2Tag.cpp
File metadata and controls
79 lines (61 loc) · 2.27 KB
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
// GNU LESSER GENERAL PUBLIC LICENSE
// Version 3, 29 June 2007
//
// Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
//
// Everyone is permitted to copy and distribute verbatim copies of this license
// document, but changing it is not allowed.
//
// This version of the GNU Lesser General Public License incorporates the terms
// and conditions of version 3 of the GNU General Public License, supplemented
// by the additional permissions listed below.
#include "stdafx.h"
#include "ID3V2Tag.h"
CID3V2Tag* CID3V2Tag::FindTag(CMPAStream* stream, bool is_appended,
unsigned begin, unsigned end) {
assert(stream);
const char* id;
unsigned offset;
if (!is_appended) {
// stands at the beginning of file (complete header is 10 bytes)
offset = begin;
id = "ID3";
} else {
// stands at the end of the file (complete footer is 10 bytes)
offset = end - 10U;
id = "3DI";
}
const unsigned char* buffer{stream->ReadBytes(10U, offset, false)};
if (memcmp(id, buffer, 3U) == 0)
return new CID3V2Tag{stream, is_appended, offset};
return nullptr;
}
CID3V2Tag::CID3V2Tag(CMPAStream* stream, bool is_appended, unsigned offset)
: CTag{stream, _T("ID3"), false, offset} {
offset += 3U;
// read out version info
const unsigned char* buffer{m_pStream->ReadBytes(3, offset)};
SetVersion(2, buffer[0], buffer[1]);
const unsigned char flags{buffer[3]};
/*m_bUnsynchronization = (bFlags & 0x80)?true:false; // bit 7
m_bExtHeader = (bFlags & 0x40)?true:false; // bit 6
m_bExperimental = (bFlags & 0x20)?true:false; // bit 5*/
const bool is_footer{(flags & 0x10) ? true : false}; // bit 4
// convert synchsafe integer
m_dwSize = GetSynchsafeInteger(m_pStream->ReadBEValue(4U, offset)) +
(is_footer ? 20U : 10U);
// for appended tag: calculate new offset
if (is_appended) m_dwOffset -= m_dwSize - 10U;
}
// return for each byte only lowest 7 bits (highest bit always zero)
unsigned CID3V2Tag::GetSynchsafeInteger(unsigned value) {
// masks first 7 bits
constexpr unsigned mask{0x7F000000U};
unsigned result{0U};
for (size_t n = 0; n < sizeof(unsigned); n++) {
result = (result << 7U) | ((value & mask) >> 24U);
value <<= 8U;
}
return result;
}
CID3V2Tag::~CID3V2Tag() {}