mirror of https://github.com/PCSX2/pcsx2.git
gsdx: Allow dump and capture PNG compression to be changed
Valid values for png_compression_level are from 0 (no compression) to 9 (max compression). The default is 1. v2: Use zlib Z_BEST_SPEED (1) and Z_BEST_COMPRESSION (9) defines.
This commit is contained in:
parent
a97cbf038c
commit
6b950d0408
|
@ -488,6 +488,8 @@ bool GSCapture::BeginCapture(float fps, GSVector2i recomendedResolution, float a
|
|||
m_size.x = theApp.GetConfig("capture_resx", 1280);
|
||||
m_size.y = theApp.GetConfig("capture_resy", 1024);
|
||||
|
||||
m_compression_level = theApp.GetConfig("png_compression_level", Z_BEST_SPEED);
|
||||
|
||||
#ifdef __linux__
|
||||
for(int i = 0; i < m_threads; i++) {
|
||||
m_workers.push_back(new GSPng::Worker());
|
||||
|
@ -524,8 +526,8 @@ bool GSCapture::DeliverFrame(const void* bits, int pitch, bool rgba)
|
|||
#elif __linux__
|
||||
|
||||
std::string out_file = m_out_dir + format("/frame.%010d.png", m_frame);
|
||||
//GSPng::Save(GSPng::RGB_PNG, out_file, (uint8*)bits, m_size.x, m_size.y, pitch);
|
||||
m_workers[m_frame%m_threads]->Push(shared_ptr<GSPng::Transaction>(new GSPng::Transaction(GSPng::RGB_PNG, out_file, static_cast<const uint8*>(bits), m_size.x, m_size.y, pitch)));
|
||||
//GSPng::Save(GSPng::RGB_PNG, out_file, (uint8*)bits, m_size.x, m_size.y, pitch, m_compression_level);
|
||||
m_workers[m_frame%m_threads]->Push(shared_ptr<GSPng::Transaction>(new GSPng::Transaction(GSPng::RGB_PNG, out_file, static_cast<const uint8*>(bits), m_size.x, m_size.y, pitch, m_compression_level)));
|
||||
|
||||
m_frame++;
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ class GSCapture
|
|||
#elif __linux__
|
||||
|
||||
vector<GSPng::Worker*> m_workers;
|
||||
int m_compression_level;
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ struct {
|
|||
namespace GSPng {
|
||||
|
||||
bool SaveFile(const string& file, Format fmt, uint8* image, uint8* row,
|
||||
int width, int height, int pitch,
|
||||
int width, int height, int pitch, int compression,
|
||||
bool rb_swapped = false, bool first_image = false)
|
||||
{
|
||||
int channel_bit_depth = pixel[fmt].channel_bit_depth;
|
||||
|
@ -71,8 +71,11 @@ namespace GSPng {
|
|||
if (setjmp(png_jmpbuf(png_ptr)))
|
||||
throw GSDXRecoverableError();
|
||||
|
||||
if (compression < 0 || compression > Z_BEST_COMPRESSION)
|
||||
compression = Z_BEST_SPEED;
|
||||
|
||||
png_init_io(png_ptr, fp);
|
||||
png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
|
||||
png_set_compression_level(png_ptr, compression);
|
||||
png_set_IHDR(png_ptr, info_ptr, width, height, channel_bit_depth, type,
|
||||
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
|
||||
png_write_info(png_ptr, info_ptr);
|
||||
|
@ -91,8 +94,7 @@ namespace GSPng {
|
|||
png_write_end(png_ptr, nullptr);
|
||||
|
||||
success = true;
|
||||
}
|
||||
catch (GSDXRecoverableError&) {
|
||||
} catch (GSDXRecoverableError&) {
|
||||
fprintf(stderr, "Failed to write image %s\n", file.c_str());
|
||||
}
|
||||
|
||||
|
@ -103,7 +105,7 @@ namespace GSPng {
|
|||
return success;
|
||||
}
|
||||
|
||||
bool Save(GSPng::Format fmt, const string& file, uint8* image, int w, int h, int pitch, bool rb_swapped)
|
||||
bool Save(GSPng::Format fmt, const string& file, uint8* image, int w, int h, int pitch, int compression, bool rb_swapped)
|
||||
{
|
||||
std::string root = file;
|
||||
root.replace(file.length() - 4, 4, "");
|
||||
|
@ -113,7 +115,7 @@ namespace GSPng {
|
|||
std::unique_ptr<uint8[]> row(new uint8[pixel[fmt].bytes_per_pixel_out * w]);
|
||||
|
||||
std::string filename = root + pixel[fmt].extension[0];
|
||||
if (!SaveFile(filename, fmt, image, row.get(), w, h, pitch, rb_swapped, true))
|
||||
if (!SaveFile(filename, fmt, image, row.get(), w, h, pitch, compression, rb_swapped, true))
|
||||
return false;
|
||||
|
||||
// Second image
|
||||
|
@ -121,11 +123,11 @@ namespace GSPng {
|
|||
return true;
|
||||
|
||||
filename = root + pixel[fmt].extension[1];
|
||||
return SaveFile(filename, fmt, image, row.get(), w, h, pitch);
|
||||
return SaveFile(filename, fmt, image, row.get(), w, h, pitch, compression);
|
||||
}
|
||||
|
||||
Transaction::Transaction(GSPng::Format fmt, const string& file, const uint8* image, int w, int h, int pitch)
|
||||
: m_fmt(fmt), m_file(file), m_w(w), m_h(h), m_pitch(pitch)
|
||||
Transaction::Transaction(GSPng::Format fmt, const string& file, const uint8* image, int w, int h, int pitch, int compression)
|
||||
: m_fmt(fmt), m_file(file), m_w(w), m_h(h), m_pitch(pitch), m_compression(compression)
|
||||
{
|
||||
// Note: yes it would be better to use shared pointer
|
||||
m_image = (uint8*)_aligned_malloc(pitch*h, 32);
|
||||
|
@ -141,7 +143,7 @@ namespace GSPng {
|
|||
|
||||
void Worker::Process(shared_ptr<Transaction>& item)
|
||||
{
|
||||
Save(item->m_fmt, item->m_file, item->m_image, item->m_w, item->m_h, item->m_pitch);
|
||||
Save(item->m_fmt, item->m_file, item->m_image, item->m_w, item->m_h, item->m_pitch, item->m_compression);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -44,12 +44,13 @@ namespace GSPng {
|
|||
int m_w;
|
||||
int m_h;
|
||||
int m_pitch;
|
||||
int m_compression;
|
||||
|
||||
Transaction(GSPng::Format fmt, const string& file, const uint8* image, int w, int h, int pitch);
|
||||
Transaction(GSPng::Format fmt, const string& file, const uint8* image, int w, int h, int pitch, int compression);
|
||||
~Transaction();
|
||||
};
|
||||
|
||||
bool Save(GSPng::Format fmt, const string& file, uint8* image, int w, int h, int pitch, bool rb_swapped = false);
|
||||
bool Save(GSPng::Format fmt, const string& file, uint8* image, int w, int h, int pitch, int compression, bool rb_swapped = false);
|
||||
|
||||
class Worker : public GSJobQueue<shared_ptr<Transaction>, 16 >
|
||||
{
|
||||
|
|
|
@ -469,7 +469,7 @@ void GSRenderer::VSync(int field)
|
|||
|
||||
if(GSTexture* t = m_dev->GetCurrent())
|
||||
{
|
||||
t->Save(m_snapshot + ".bmp");
|
||||
t->Save(m_snapshot + ".bmp", true);
|
||||
}
|
||||
|
||||
m_snapshot.clear();
|
||||
|
|
|
@ -445,13 +445,13 @@ void GSRendererHW::Draw()
|
|||
(int)context->CLAMP.MINU, (int)context->CLAMP.MAXU,
|
||||
(int)context->CLAMP.MINV, (int)context->CLAMP.MAXV);
|
||||
|
||||
tex->m_texture->Save(root_hw+s, true);
|
||||
tex->m_texture->Save(root_hw+s, false, true);
|
||||
|
||||
if(tex->m_palette)
|
||||
{
|
||||
s = format("%05d_f%lld_tpx_%05x_%d.dds", s_n, frame, context->TEX0.CBP, context->TEX0.CPSM);
|
||||
|
||||
tex->m_palette->Save(root_hw+s, true);
|
||||
tex->m_palette->Save(root_hw+s, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ public:
|
|||
virtual bool Update(const GSVector4i& r, const void* data, int pitch) = 0;
|
||||
virtual bool Map(GSMap& m, const GSVector4i* r = NULL) = 0;
|
||||
virtual void Unmap() = 0;
|
||||
virtual bool Save(const string& fn, bool dds = false) = 0;
|
||||
virtual bool Save(const string& fn, bool user_image = false, bool dds = false) = 0;
|
||||
virtual void Invalidate() {}
|
||||
virtual uint32 GetID() { return 0; }
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ void GSTexture11::Unmap()
|
|||
}
|
||||
}
|
||||
|
||||
bool GSTexture11::Save(const string& fn, bool dds)
|
||||
bool GSTexture11::Save(const string& fn, bool user_image, bool dds)
|
||||
{
|
||||
CComPtr<ID3D11Texture2D> res;
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
|
@ -179,7 +179,8 @@ bool GSTexture11::Save(const string& fn, bool dds)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool success = GSPng::Save(format, fn, static_cast<uint8*>(sm.pData), desc.Width, desc.Height, sm.RowPitch);
|
||||
int compression = user_image ? Z_BEST_COMPRESSION : theApp.GetConfig("png_compression_level", Z_BEST_SPEED);
|
||||
bool success = GSPng::Save(format, fn, static_cast<uint8*>(sm.pData), desc.Width, desc.Height, sm.RowPitch, compression);
|
||||
|
||||
m_ctx->Unmap(res, 0);
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ public:
|
|||
bool Update(const GSVector4i& r, const void* data, int pitch);
|
||||
bool Map(GSMap& m, const GSVector4i* r);
|
||||
void Unmap();
|
||||
bool Save(const string& fn, bool dds = false);
|
||||
bool Save(const string& fn, bool user_image = false, bool dds = false);
|
||||
|
||||
operator ID3D11Texture2D*();
|
||||
operator ID3D11ShaderResourceView*();
|
||||
|
|
|
@ -142,7 +142,7 @@ void GSTexture9::Unmap()
|
|||
}
|
||||
}
|
||||
|
||||
bool GSTexture9::Save(const string& fn, bool dds)
|
||||
bool GSTexture9::Save(const string& fn, bool user_image, bool dds)
|
||||
{
|
||||
bool rb_swapped = true;
|
||||
CComPtr<IDirect3DSurface9> surface;
|
||||
|
@ -201,7 +201,8 @@ bool GSTexture9::Save(const string& fn, bool dds)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool success = GSPng::Save(format, fn, static_cast<uint8*>(slr.pBits), desc.Width, desc.Height, slr.Pitch, rb_swapped);
|
||||
int compression = user_image ? Z_BEST_COMPRESSION : theApp.GetConfig("png_compression_level", Z_BEST_SPEED);
|
||||
bool success = GSPng::Save(format, fn, static_cast<uint8*>(slr.pBits), desc.Width, desc.Height, slr.Pitch, compression, rb_swapped);
|
||||
|
||||
surface->UnlockRect();
|
||||
return success;
|
||||
|
|
|
@ -38,7 +38,7 @@ public:
|
|||
bool Update(const GSVector4i& r, const void* data, int pitch);
|
||||
bool Map(GSMap& m, const GSVector4i* r);
|
||||
void Unmap();
|
||||
bool Save(const string& fn, bool dds = false);
|
||||
bool Save(const string& fn, bool user_image = false, bool dds = false);
|
||||
|
||||
operator IDirect3DSurface9*();
|
||||
operator IDirect3DTexture9*();
|
||||
|
|
|
@ -37,5 +37,5 @@ public:
|
|||
bool Update(const GSVector4i& r, const void* data, int pitch) {return true;}
|
||||
bool Map(GSMap& m, const GSVector4i* r) {return false;}
|
||||
void Unmap() {}
|
||||
bool Save(const string& fn, bool dds = false) {return false;}
|
||||
bool Save(const string& fn, bool user_image = false, bool dds = false) { return false; }
|
||||
};
|
||||
|
|
|
@ -421,7 +421,7 @@ void GSTextureOGL::Unmap()
|
|||
{
|
||||
}
|
||||
|
||||
bool GSTextureOGL::Save(const string& fn, bool dds)
|
||||
bool GSTextureOGL::Save(const string& fn, bool user_image, bool dds)
|
||||
{
|
||||
// Collect the texture data
|
||||
uint32 pitch = 4 * m_size.x;
|
||||
|
@ -470,7 +470,8 @@ bool GSTextureOGL::Save(const string& fn, bool dds)
|
|||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
return GSPng::Save(fmt, fn, image.get(), m_size.x, m_size.y, pitch);
|
||||
int compression = user_image ? Z_BEST_COMPRESSION : theApp.GetConfig("png_compression_level", Z_BEST_SPEED);
|
||||
return GSPng::Save(fmt, fn, image.get(), m_size.x, m_size.y, pitch, compression);
|
||||
}
|
||||
|
||||
uint32 GSTextureOGL::GetMemUsage()
|
||||
|
|
|
@ -63,7 +63,7 @@ class GSTextureOGL : public GSTexture
|
|||
bool Update(const GSVector4i& r, const void* data, int pitch);
|
||||
bool Map(GSMap& m, const GSVector4i* r = NULL);
|
||||
void Unmap();
|
||||
bool Save(const string& fn, bool dds = false);
|
||||
bool Save(const string& fn, bool user_image = false, bool dds = false);
|
||||
|
||||
bool IsBackbuffer() { return (m_type == GSTexture::Backbuffer); }
|
||||
bool IsDss() { return (m_type == GSTexture::DepthStencil); }
|
||||
|
|
|
@ -85,7 +85,7 @@ void GSTextureSW::Unmap()
|
|||
m_mapped.clear();
|
||||
}
|
||||
|
||||
bool GSTextureSW::Save(const string& fn, bool dds)
|
||||
bool GSTextureSW::Save(const string& fn, bool user_image, bool dds)
|
||||
{
|
||||
if(dds) return false; // not implemented
|
||||
|
||||
|
@ -94,5 +94,6 @@ bool GSTextureSW::Save(const string& fn, bool dds)
|
|||
#else
|
||||
GSPng::Format fmt = GSPng::RGB_PNG;
|
||||
#endif
|
||||
return GSPng::Save(fmt, fn, static_cast<uint8*>(m_data), m_size.x, m_size.y, m_pitch);
|
||||
int compression = user_image ? Z_BEST_COMPRESSION : theApp.GetConfig("png_compression_level", Z_BEST_SPEED);
|
||||
return GSPng::Save(fmt, fn, static_cast<uint8*>(m_data), m_size.x, m_size.y, m_pitch, compression);
|
||||
}
|
||||
|
|
|
@ -38,5 +38,5 @@ public:
|
|||
bool Update(const GSVector4i& r, const void* data, int pitch);
|
||||
bool Map(GSMap& m, const GSVector4i* r);
|
||||
void Unmap();
|
||||
bool Save(const string& fn, bool dds = false);
|
||||
bool Save(const string& fn, bool user_image = false, bool dds = false);
|
||||
};
|
||||
|
|
|
@ -109,6 +109,8 @@ using namespace std;
|
|||
|
||||
#include <memory>
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
#if _MSC_VER >= 1800 || !defined(_WIN32)
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
|
Loading…
Reference in New Issue