mirror of https://github.com/stella-emu/stella.git
(MovieCart) Limit reading of image data to single frame
when its likely an MVC file. This avoids reading of GB of data.
This commit is contained in:
parent
a92a33b4da
commit
44e15ff86f
|
@ -19,6 +19,7 @@
|
|||
#include "Logger.hxx"
|
||||
|
||||
#include "CartDetector.hxx"
|
||||
#include "MovieCart/StreamReader.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t size)
|
||||
|
@ -694,11 +695,34 @@ bool CartDetector::isProbablyMDM(const ByteBuffer& image, size_t size)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool CartDetector::isProbablyMVC(const ByteBuffer& image, size_t size)
|
||||
{
|
||||
// MVC version 0, frame 0
|
||||
// MVC version 0
|
||||
uInt8 sig[] = { 'M', 'V', 'C', 0 };
|
||||
return searchForBytes(image, std::min<size_t>(size, 5), sig, 4);
|
||||
int sigSize = sizeof(sig);
|
||||
return searchForBytes(image, std::min<size_t>(size, sigSize+1), sig, sigSize);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
size_t CartDetector::isProbablyMVC(std::istream &in, size_t maxSize)
|
||||
{
|
||||
const size_t frameSize = 2 * MVC_FIELD_PAD_SIZE;
|
||||
bool found = false;
|
||||
|
||||
// Returns size of field if stream is probably an MVC movie cartridge
|
||||
|
||||
if (maxSize >= frameSize)
|
||||
{
|
||||
auto pos = in.tellg();
|
||||
|
||||
ByteBuffer image = make_unique<uInt8[]>(frameSize);
|
||||
in.read(reinterpret_cast<char*>(image.get()), frameSize);
|
||||
|
||||
in.seekg(pos);
|
||||
|
||||
found = isProbablyMVC(image, frameSize);
|
||||
}
|
||||
|
||||
return found ? frameSize : 0;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool CartDetector::isProbablySB(const ByteBuffer& image, size_t size)
|
||||
|
|
|
@ -40,6 +40,13 @@ class CartDetector
|
|||
*/
|
||||
static Bankswitch::Type autodetectType(const ByteBuffer& image, size_t size);
|
||||
|
||||
|
||||
/**
|
||||
MVC cartridges are of arbitary large length
|
||||
Returns size of frame if stream is probably an MVC movie cartridge
|
||||
*/
|
||||
static size_t isProbablyMVC(std::istream &in, size_t size);
|
||||
|
||||
private:
|
||||
/**
|
||||
Search the image for the specified byte signature
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "FSNodeFactory.hxx"
|
||||
#include "FSNode.hxx"
|
||||
#include "CartDetector.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FilesystemNode::FilesystemNode(const AbstractFSNodePtr& realNode)
|
||||
|
@ -355,6 +356,12 @@ size_t FilesystemNode::read(ByteBuffer& buffer) const
|
|||
if (sizeRead == 0)
|
||||
throw runtime_error("Zero-byte file");
|
||||
|
||||
// In the case of MVC (MovieCart) files, contents are streaming data
|
||||
// of arbitrary length, so just read first frame.
|
||||
size_t subSize = CartDetector::isProbablyMVC(in, sizeRead);
|
||||
if (subSize > 0)
|
||||
sizeRead = subSize;
|
||||
|
||||
buffer = make_unique<uInt8[]>(sizeRead);
|
||||
in.read(reinterpret_cast<char*>(buffer.get()), sizeRead);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue