2020-10-04 10:30:18 +02:00
|
|
|
#include <cstring>
|
|
|
|
|
|
2017-12-04 17:41:06 +01:00
|
|
|
#include "Common/Log.h"
|
2020-10-04 00:25:21 +02:00
|
|
|
#include "Common/Data/Format/RIFF.h"
|
2017-12-04 17:41:06 +01:00
|
|
|
|
2017-12-04 17:23:29 +01:00
|
|
|
inline uint32_t flipID(uint32_t id) {
|
|
|
|
|
return ((id >> 24) & 0xFF) | ((id >> 8) & 0xFF00) | ((id << 8) & 0xFF0000) | ((id << 24) & 0xFF000000);
|
|
|
|
|
}
|
2012-03-24 23:39:19 +01:00
|
|
|
|
2017-12-04 17:27:47 +01:00
|
|
|
RIFFReader::RIFFReader(const uint8_t *data, int dataSize) {
|
2017-12-04 17:23:29 +01:00
|
|
|
data_ = new uint8_t[dataSize];
|
|
|
|
|
memcpy(data_, data, dataSize);
|
|
|
|
|
depth_ = 0;
|
|
|
|
|
pos_ = 0;
|
|
|
|
|
eof_ = dataSize;
|
2017-12-04 18:01:51 +01:00
|
|
|
fileSize_ = dataSize;
|
2014-06-22 17:41:15 +02:00
|
|
|
}
|
|
|
|
|
|
2017-12-04 17:27:47 +01:00
|
|
|
RIFFReader::~RIFFReader() {
|
2017-12-04 17:29:48 +01:00
|
|
|
delete[] data_;
|
2012-03-24 23:39:19 +01:00
|
|
|
}
|
|
|
|
|
|
2017-12-04 17:33:42 +01:00
|
|
|
int RIFFReader::ReadInt() {
|
2024-07-22 11:36:12 +02:00
|
|
|
int value = 0;
|
2017-12-04 17:41:06 +01:00
|
|
|
if (data_ && pos_ < eof_ - 3) {
|
2017-12-04 17:23:29 +01:00
|
|
|
pos_ += 4;
|
2024-07-22 11:36:12 +02:00
|
|
|
memcpy(&value, data_ + pos_ - 4, 4);
|
2012-10-31 13:23:16 +01:00
|
|
|
}
|
2024-07-22 11:36:12 +02:00
|
|
|
return value;
|
2012-03-24 23:39:19 +01:00
|
|
|
}
|
|
|
|
|
|
2017-12-04 18:01:51 +01:00
|
|
|
bool RIFFReader::Descend(uint32_t intoId) {
|
2017-12-04 17:23:29 +01:00
|
|
|
if (depth_ > 30)
|
2016-12-01 22:07:03 +01:00
|
|
|
return false;
|
|
|
|
|
|
2017-12-04 18:01:51 +01:00
|
|
|
intoId = flipID(intoId);
|
2017-12-04 17:27:47 +01:00
|
|
|
bool found = false;
|
2012-03-24 23:39:19 +01:00
|
|
|
|
2017-12-04 17:27:47 +01:00
|
|
|
// save information to restore after the next Ascend
|
|
|
|
|
stack[depth_].parentStartLocation = pos_;
|
|
|
|
|
stack[depth_].parentEOF = eof_;
|
2012-03-24 23:39:19 +01:00
|
|
|
|
2017-12-04 17:27:47 +01:00
|
|
|
// let's search through children..
|
|
|
|
|
while (pos_ < eof_) {
|
2017-12-04 18:01:51 +01:00
|
|
|
int id = ReadInt();
|
|
|
|
|
int length = ReadInt();
|
|
|
|
|
int startLocation = pos_;
|
2017-12-04 17:27:47 +01:00
|
|
|
|
2017-12-04 18:01:51 +01:00
|
|
|
if (pos_ + length > fileSize_) {
|
2024-07-14 14:42:59 +02:00
|
|
|
ERROR_LOG(Log::IO, "Block extends outside of RIFF file - failing descend");
|
2017-12-04 18:01:51 +01:00
|
|
|
pos_ = stack[depth_].parentStartLocation;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (id == intoId) {
|
|
|
|
|
stack[depth_].ID = intoId;
|
|
|
|
|
stack[depth_].length = length;
|
|
|
|
|
stack[depth_].startLocation = startLocation;
|
2017-12-04 17:27:47 +01:00
|
|
|
found = true;
|
|
|
|
|
break;
|
|
|
|
|
} else {
|
2017-12-04 18:01:51 +01:00
|
|
|
if (length > 0) {
|
|
|
|
|
pos_ += length; // try next block
|
2017-12-04 17:41:06 +01:00
|
|
|
} else {
|
2024-07-14 14:42:59 +02:00
|
|
|
ERROR_LOG(Log::IO, "Bad data in RIFF file : block length %d. Not descending.", length);
|
2017-12-04 17:41:06 +01:00
|
|
|
pos_ = stack[depth_].parentStartLocation;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2017-12-04 17:27:47 +01:00
|
|
|
}
|
2012-10-31 13:23:16 +01:00
|
|
|
}
|
2017-12-04 17:27:47 +01:00
|
|
|
|
|
|
|
|
// if we found nothing, return false so the caller can skip this
|
|
|
|
|
if (!found) {
|
2017-12-04 17:33:42 +01:00
|
|
|
pos_ = stack[depth_].parentStartLocation;
|
2017-12-04 17:27:47 +01:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// descend into it
|
|
|
|
|
// pos was set inside the loop above
|
|
|
|
|
eof_ = stack[depth_].startLocation + stack[depth_].length;
|
|
|
|
|
depth_++;
|
|
|
|
|
return true;
|
2012-03-24 23:39:19 +01:00
|
|
|
}
|
|
|
|
|
|
2017-12-04 17:33:42 +01:00
|
|
|
void RIFFReader::Ascend() {
|
2017-12-04 17:27:47 +01:00
|
|
|
// ascend, and restore information
|
|
|
|
|
depth_--;
|
2017-12-04 17:33:42 +01:00
|
|
|
pos_ = stack[depth_].parentStartLocation;
|
2017-12-04 17:27:47 +01:00
|
|
|
eof_ = stack[depth_].parentEOF;
|
2012-03-24 23:39:19 +01:00
|
|
|
}
|
|
|
|
|
|
2017-12-04 17:33:42 +01:00
|
|
|
void RIFFReader::ReadData(void *what, int count) {
|
2017-12-04 17:29:48 +01:00
|
|
|
memcpy(what, data_ + pos_, count);
|
2017-12-04 17:23:29 +01:00
|
|
|
pos_ += count;
|
2012-10-31 13:23:16 +01:00
|
|
|
count &= 3;
|
|
|
|
|
if (count) {
|
2017-12-04 17:23:29 +01:00
|
|
|
count = 4 - count;
|
|
|
|
|
pos_ += count;
|
2012-10-31 13:23:16 +01:00
|
|
|
}
|
2012-03-24 23:39:19 +01:00
|
|
|
}
|
|
|
|
|
|
2017-12-04 17:33:42 +01:00
|
|
|
int RIFFReader::GetCurrentChunkSize() {
|
2017-12-04 17:23:29 +01:00
|
|
|
if (depth_)
|
|
|
|
|
return stack[depth_ - 1].length;
|
2012-10-31 13:23:16 +01:00
|
|
|
else
|
|
|
|
|
return 0;
|
2012-03-24 23:39:19 +01:00
|
|
|
}
|