mirror of https://github.com/stella-emu/stella.git
enhanced multiple image sorting
improved image memory allocation
This commit is contained in:
parent
fea886d4b6
commit
34618aab46
|
@ -49,13 +49,13 @@ void JPGLibrary::loadImage(const string& filename, FBSurface& surface,
|
||||||
in.seekg(0);
|
in.seekg(0);
|
||||||
|
|
||||||
// Create space for the entire file
|
// Create space for the entire file
|
||||||
if(size > myFileBuffer.size())
|
if(size > myFileBuffer.capacity())
|
||||||
myFileBuffer.resize(size);
|
myFileBuffer.reserve(size * 1.5);
|
||||||
if(!in.read(myFileBuffer.data(), size))
|
if(!in.read(myFileBuffer.data(), size))
|
||||||
loadImageERROR("Image data reading failed");
|
loadImageERROR("JPG image data reading failed");
|
||||||
|
|
||||||
if(njDecode(myFileBuffer.data(), static_cast<int>(size)))
|
if(njDecode(myFileBuffer.data(), static_cast<int>(size)))
|
||||||
loadImageERROR("Error decoding the input file");
|
loadImageERROR("Error decoding the JPG image");
|
||||||
|
|
||||||
// Read the entire image in one go
|
// Read the entire image in one go
|
||||||
myReadInfo.buffer = njGetImage();
|
myReadInfo.buffer = njGetImage();
|
||||||
|
|
|
@ -49,18 +49,18 @@ void PNGLibrary::loadImage(const string& filename, FBSurface& surface, VariantLi
|
||||||
|
|
||||||
std::ifstream in(filename, std::ios_base::binary);
|
std::ifstream in(filename, std::ios_base::binary);
|
||||||
if(!in.is_open())
|
if(!in.is_open())
|
||||||
loadImageERROR("No snapshot found");
|
loadImageERROR("No image found");
|
||||||
|
|
||||||
// Create the PNG loading context structure
|
// Create the PNG loading context structure
|
||||||
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr,
|
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr,
|
||||||
png_user_error, png_user_warn);
|
png_user_error, png_user_warn);
|
||||||
if(png_ptr == nullptr)
|
if(png_ptr == nullptr)
|
||||||
loadImageERROR("Couldn't allocate memory for PNG file");
|
loadImageERROR("Couldn't allocate memory for PNG image");
|
||||||
|
|
||||||
// Allocate/initialize the memory for image information. REQUIRED.
|
// Allocate/initialize the memory for image information. REQUIRED.
|
||||||
info_ptr = png_create_info_struct(png_ptr);
|
info_ptr = png_create_info_struct(png_ptr);
|
||||||
if(info_ptr == nullptr)
|
if(info_ptr == nullptr)
|
||||||
loadImageERROR("Couldn't create image information for PNG file");
|
loadImageERROR("Couldn't create image information for PNG image");
|
||||||
|
|
||||||
// Set up the input control
|
// Set up the input control
|
||||||
png_set_read_fn(png_ptr, &in, png_read_data);
|
png_set_read_fn(png_ptr, &in, png_read_data);
|
||||||
|
@ -97,7 +97,7 @@ void PNGLibrary::loadImage(const string& filename, FBSurface& surface, VariantLi
|
||||||
|
|
||||||
// Create/initialize storage area for the current image
|
// Create/initialize storage area for the current image
|
||||||
if(!allocateStorage(iwidth, iheight))
|
if(!allocateStorage(iwidth, iheight))
|
||||||
loadImageERROR("Not enough memory to read PNG file");
|
loadImageERROR("Not enough memory to read PNG image");
|
||||||
|
|
||||||
// The PNG read function expects an array of rows, not a single 1-D array
|
// The PNG read function expects an array of rows, not a single 1-D array
|
||||||
for(uInt32 irow = 0, offset = 0; irow < ReadInfo.height; ++irow, offset += ReadInfo.pitch)
|
for(uInt32 irow = 0, offset = 0; irow < ReadInfo.height; ++irow, offset += ReadInfo.pitch)
|
||||||
|
@ -385,12 +385,12 @@ bool PNGLibrary::allocateStorage(png_uint_32 w, png_uint_32 h)
|
||||||
{
|
{
|
||||||
// Create space for the entire image (3 bytes per pixel in RGB format)
|
// Create space for the entire image (3 bytes per pixel in RGB format)
|
||||||
const size_t req_buffer_size = w * h * 3;
|
const size_t req_buffer_size = w * h * 3;
|
||||||
if(req_buffer_size > ReadInfo.buffer.size())
|
if(req_buffer_size > ReadInfo.buffer.capacity())
|
||||||
ReadInfo.buffer.resize(req_buffer_size);
|
ReadInfo.buffer.reserve(req_buffer_size * 1.5);
|
||||||
|
|
||||||
const size_t req_row_size = h;
|
const size_t req_row_size = h;
|
||||||
if(req_row_size > ReadInfo.row_pointers.size())
|
if(req_row_size > ReadInfo.row_pointers.capacity())
|
||||||
ReadInfo.row_pointers.resize(req_row_size);
|
ReadInfo.row_pointers.reserve(req_row_size * 1.5);
|
||||||
|
|
||||||
ReadInfo.width = w;
|
ReadInfo.width = w;
|
||||||
ReadInfo.height = h;
|
ReadInfo.height = h;
|
||||||
|
|
|
@ -90,6 +90,7 @@ void RomImageWidget::reloadProperties(const FSNode& node)
|
||||||
void RomImageWidget::parseProperties(const FSNode& node, bool full)
|
void RomImageWidget::parseProperties(const FSNode& node, bool full)
|
||||||
{
|
{
|
||||||
uInt64 startTime = TimerManager::getTicks() / 1000;
|
uInt64 startTime = TimerManager::getTicks() / 1000;
|
||||||
|
|
||||||
if(myNavSurface == nullptr)
|
if(myNavSurface == nullptr)
|
||||||
{
|
{
|
||||||
// Create navigation surface
|
// Create navigation surface
|
||||||
|
@ -154,7 +155,8 @@ void RomImageWidget::parseProperties(const FSNode& node, bool full)
|
||||||
|
|
||||||
// Try to find all snapshots by property and ROM file name
|
// Try to find all snapshots by property and ROM file name
|
||||||
myImageList.clear();
|
myImageList.clear();
|
||||||
getImageList(myProperties.get(PropType::Cart_Name), node.getNameWithExt());
|
getImageList(myProperties.get(PropType::Cart_Name), node.getNameWithExt(),
|
||||||
|
oldFileName);
|
||||||
|
|
||||||
// The first file found before must not be the first file now, if files by
|
// The first file found before must not be the first file now, if files by
|
||||||
// property *and* ROM name are found (TODO: fix that!)
|
// property *and* ROM name are found (TODO: fix that!)
|
||||||
|
@ -191,13 +193,14 @@ bool RomImageWidget::changeImage(int direction)
|
||||||
|
|
||||||
#ifdef IMAGE_SUPPORT
|
#ifdef IMAGE_SUPPORT
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool RomImageWidget::getImageList(const string& propName, const string& romName)
|
bool RomImageWidget::getImageList(const string& propName, const string& romName,
|
||||||
|
const string& oldFileName)
|
||||||
{
|
{
|
||||||
const std::regex symbols{R"([-[\]{}()*+?.,\^$|#])"}; // \s
|
const std::regex symbols{R"([-[\]{}()*+?.,\^$|#])"}; // \s
|
||||||
const string rgxPropName = std::regex_replace(propName, symbols, R"(\$&)");
|
const string rgxPropName = std::regex_replace(propName, symbols, R"(\$&)");
|
||||||
const string rgxRomName = std::regex_replace(romName, symbols, R"(\$&)");
|
const string rgxRomName = std::regex_replace(romName, symbols, R"(\$&)");
|
||||||
// Look for <name.png|jpg> or <name_#.png|jpg> (# is a number)
|
// Look for <name.png|jpg> or <name_#.png|jpg> (# is a number)
|
||||||
const std::regex rgx("^(" + rgxPropName + "|" + rgxRomName + ")(_\\d+){0,1}\\.(png|jpg)$");
|
const std::regex rgx("^(" + rgxPropName + "|" + rgxRomName + ")(_\\d+)?\\.(png|jpg)$");
|
||||||
|
|
||||||
FSNode::NameFilter filter = ([&](const FSNode& node)
|
FSNode::NameFilter filter = ([&](const FSNode& node)
|
||||||
{
|
{
|
||||||
|
@ -212,14 +215,17 @@ bool RomImageWidget::getImageList(const string& propName, const string& romName)
|
||||||
// Sort again, not considering extensions, else <filename.png|jpg> would be at
|
// Sort again, not considering extensions, else <filename.png|jpg> would be at
|
||||||
// the end of the list
|
// the end of the list
|
||||||
std::sort(myImageList.begin(), myImageList.end(),
|
std::sort(myImageList.begin(), myImageList.end(),
|
||||||
[](const FSNode& node1, const FSNode& node2)
|
[oldFileName](const FSNode& node1, const FSNode& node2)
|
||||||
{
|
{
|
||||||
int compare = BSPF::compareIgnoreCase(node1.getNameWithExt(), node2.getNameWithExt());
|
int compare = BSPF::compareIgnoreCase(node1.getNameWithExt(), node2.getNameWithExt());
|
||||||
return
|
return
|
||||||
compare < 0 ||
|
compare < 0 ||
|
||||||
|
// PNGs first!
|
||||||
(compare == 0 &&
|
(compare == 0 &&
|
||||||
node1.getName().substr(node1.getName().find_last_of('.') + 1) >
|
node1.getName().substr(node1.getName().find_last_of('.') + 1) >
|
||||||
node2.getName().substr(node2.getName().find_last_of('.') + 1)); // PNGs first!
|
node2.getName().substr(node2.getName().find_last_of('.') + 1)) ||
|
||||||
|
// Make sure that first image found in initial load is first image now too
|
||||||
|
node1.getName() == oldFileName;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
return myImageList.size() > 0;
|
return myImageList.size() > 0;
|
||||||
|
@ -348,7 +354,7 @@ void RomImageWidget::drawWidget(bool hilite)
|
||||||
FBSurface& s = dialog().surface();
|
FBSurface& s = dialog().surface();
|
||||||
const int yoff = myImageHeight;
|
const int yoff = myImageHeight;
|
||||||
|
|
||||||
s.fillRect(_x+1, _y+1, _w-2, _h-2, _bgcolor);
|
s.fillRect(_x, _y + 1, _w, _h - 1, _bgcolor);
|
||||||
s.frameRect(_x, _y, _w, myImageHeight, kColor);
|
s.frameRect(_x, _y, _w, myImageHeight, kColor);
|
||||||
|
|
||||||
if(!myHaveProperties)
|
if(!myHaveProperties)
|
||||||
|
|
|
@ -35,7 +35,8 @@ class RomImageWidget : public Widget
|
||||||
return font.getFontHeight() * 9 / 8;
|
return font.getFontHeight() * 9 / 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setProperties(const FSNode& node, const Properties properties, bool full = true);
|
void setProperties(const FSNode& node, const Properties properties,
|
||||||
|
bool full = true);
|
||||||
void clearProperties();
|
void clearProperties();
|
||||||
void reloadProperties(const FSNode& node);
|
void reloadProperties(const FSNode& node);
|
||||||
bool changeImage(int direction = 1);
|
bool changeImage(int direction = 1);
|
||||||
|
@ -52,7 +53,8 @@ class RomImageWidget : public Widget
|
||||||
private:
|
private:
|
||||||
void parseProperties(const FSNode& node, bool full = true);
|
void parseProperties(const FSNode& node, bool full = true);
|
||||||
#ifdef IMAGE_SUPPORT
|
#ifdef IMAGE_SUPPORT
|
||||||
bool getImageList(const string& propName, const string& romName);
|
bool getImageList(const string& propName, const string& romName,
|
||||||
|
const string& oldFileName);
|
||||||
bool tryImageFormats(string& fileName);
|
bool tryImageFormats(string& fileName);
|
||||||
bool loadImage(const string& fileName);
|
bool loadImage(const string& fileName);
|
||||||
bool loadPng(const string& fileName);
|
bool loadPng(const string& fileName);
|
||||||
|
|
Loading…
Reference in New Issue