Files
wc3re/mvedecode.cc

109 lines
2.4 KiB
C++

#include <cstdio>
#include <cstring>
#include <cerrno>
#include <cstdint>
#include <memory>
#include <limits>
#include <unistd.h>
#include "common.hh"
#include "util.hh"
#include "TreFile.hh"
#include "IffFile.hh"
#include "MveDecoder.hh"
void usage(char *argv0) {
fprintf(stderr, "Usage: %s [-h] (tre-file name/crc)/iff-file\n", argv0);
fprintf(stderr, "\tAttempt to decode the movie stored in iff-file, or in the\n\tiff-object \"name\"/\"crc\" contained in tre-file\n");
fprintf(stderr, "\t-p [id]\tPlay branch id, or all branches if no id given\n");
fprintf(stderr, "\t-h\tPrint this help\n");
}
int main(int argc, char *argv[]) {
std::string inFile, objectSpec;
int branch = -1;
bool useTre = false, play = false;
{
int opt;
while ((opt = getopt(argc, argv, "hp::")) != -1) {
switch (opt) {
case 'h':
usage(argv[0]);
return 0;
case 'p':
play = true;
if (optarg) {
try {
branch = std::stoi(optarg, nullptr, 10);
} catch (std::invalid_argument &ex) {
} catch (std::out_of_range &ex) {
}
}
break;
default:
usage(argv[0]);
return 1;
}
}
if (optind >= argc) {
usage(argv[0]);
return 1;
}
inFile = argv[optind++];
if (optind < argc) {
useTre = true;
objectSpec = argv[optind];
}
}
try {
MmapFile mmap{inFile};
std::unique_ptr<TreFile> tre;
TreFile::Object object;
std::unique_ptr<MveDecoder> mve;
if (useTre) {
tre = std::make_unique<TreFile>(mmap.data(), mmap.size());
// Try to parse objectSpec as CRC
try {
unsigned long CRC = std::stoul(objectSpec, nullptr, 16);
if (CRC <= std::numeric_limits<uint32_t>::max()) {
object = tre->openCRC(CRC);
}
} catch (std::invalid_argument &ex) {
} catch (std::out_of_range &ex) {
}
if (!object) // Wasn't a CRC, try as name
object = tre->openName(objectSpec);
mve = std::make_unique<MveDecoder>(object.data(), object.size());
} else
mve = std::make_unique<MveDecoder>(mmap.data(), mmap.size());
if (play) {
if (branch >= 0)
mve->play(branch);
else
for(unsigned i = 0;i < mve->numBranches();++i)
mve->play(i);
}
} catch (POSIXException &ex) {
fflush(stdout);
fprintf(stderr, "%s\n", ex.toString().c_str());
return 2;
} catch (Exception &ex) {
fflush(stdout);
fprintf(stderr, "%s\n", ex.toString().c_str());
return 3;
}
return 0;
}