-
Notifications
You must be signed in to change notification settings - Fork 3
/
isLossless.cpp
76 lines (63 loc) · 1.96 KB
/
isLossless.cpp
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
#include <iostream>
#include <cstdio>
#include <limits.h>
#include "m4a_file.hpp"
bool gPrintLossless = true;
bool gDebug = false;
// We're looking for a 'stsd' atom
struct AtomCallback {
int isLossless;
AtomCallback() { isLossless = -1; }
void operator() (const M4AFile *f, M4AFile::AtomType atom, size_t start, size_t length, size_t depth)
{
if (gDebug)
std::cout << std::string(depth, ' ') << "'" << f->AtomName(atom) << "' (" << length << " bytes)" << std::endl;
if ('stsd' == atom)
{
if (gDebug)
std::cout << "Found a 'stsd' at offset " << start << std::endl;
if (length < 16)
throw std::runtime_error("'stsd' atom is too small");
isLossless = f->read32 ( start + 12 ) == 0x616C6163 ? 1 : 0;
}
}
};
void ProcessAFile (const char *fileName) {
try {
M4AFile f(fileName);
if (gDebug) {
std::cout << "Processing " << fileName << std::endl;
std::cout << "File is " << f.size() << " bytes long" << std::endl;
}
AtomCallback cb;
f.ForEachAtomDo(std::ref(cb));
if (cb.isLossless < 0)
throw std::runtime_error("does not have a 'stsd' atom");
else if (cb.isLossless == gPrintLossless)
std::cout << fileName << std::endl;
}
catch (const std::runtime_error &e) {
std::cerr << "## File '" << fileName << "': " << e.what() << std::endl;
}
}
int main (int argc, char *argv [])
{
if (argc == 1) {
std::cout << "Usage: " << argv[0] << " [-!] [-n] [-d] <list of files" << std::endl;
std::cout << " prints the path of files that encoded with Apple lossless encoder" << std::endl;
std::cout << " if -! or -n is specified, prints the path of files NOT encoded lossless" << std::endl;
return 0;
}
int startArg = 1;
if ((std::strcmp ( argv[startArg], "-!" ) == 0) || (std::strcmp ( argv[startArg], "-n" ) == 0)) {
gPrintLossless = false;
startArg = 2;
}
if (std::strcmp ( argv[startArg], "-d" ) == 0) {
gDebug = true;
startArg++;
}
for (int i = startArg; i < argc; ++i)
ProcessAFile(argv[i]);
return 0;
}