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 "Logger.hxx"
|
||||||
|
|
||||||
#include "CartDetector.hxx"
|
#include "CartDetector.hxx"
|
||||||
|
#include "MovieCart/StreamReader.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t size)
|
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)
|
bool CartDetector::isProbablyMVC(const ByteBuffer& image, size_t size)
|
||||||
{
|
{
|
||||||
// MVC version 0, frame 0
|
// MVC version 0
|
||||||
uInt8 sig[] = { 'M', 'V', 'C', 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)
|
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);
|
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:
|
private:
|
||||||
/**
|
/**
|
||||||
Search the image for the specified byte signature
|
Search the image for the specified byte signature
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#include "FSNodeFactory.hxx"
|
#include "FSNodeFactory.hxx"
|
||||||
#include "FSNode.hxx"
|
#include "FSNode.hxx"
|
||||||
|
#include "CartDetector.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
FilesystemNode::FilesystemNode(const AbstractFSNodePtr& realNode)
|
FilesystemNode::FilesystemNode(const AbstractFSNodePtr& realNode)
|
||||||
|
@ -355,6 +356,12 @@ size_t FilesystemNode::read(ByteBuffer& buffer) const
|
||||||
if (sizeRead == 0)
|
if (sizeRead == 0)
|
||||||
throw runtime_error("Zero-byte file");
|
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);
|
buffer = make_unique<uInt8[]>(sizeRead);
|
||||||
in.read(reinterpret_cast<char*>(buffer.get()), sizeRead);
|
in.read(reinterpret_cast<char*>(buffer.get()), sizeRead);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue