2010-06-11 15:38:17 +00:00
|
|
|
//============================================================================
|
|
|
|
//
|
|
|
|
// SSSS tt lll lll
|
|
|
|
// SS SS tt ll ll
|
|
|
|
// SS tttttt eeee ll ll aaaa
|
|
|
|
// SSSS tt ee ee ll ll aa
|
|
|
|
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
|
|
|
// SS SS tt ee ll ll aa aa
|
|
|
|
// SSSS ttt eeeee llll llll aaaaa
|
|
|
|
//
|
2019-12-31 17:18:56 +00:00
|
|
|
// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
|
2010-06-11 15:38:17 +00:00
|
|
|
// and the Stella Team
|
|
|
|
//
|
|
|
|
// See the file "License.txt" for information on usage and redistribution of
|
|
|
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
|
|
|
//============================================================================
|
|
|
|
|
2019-05-02 20:28:39 +00:00
|
|
|
#if defined(PNG_SUPPORT)
|
|
|
|
|
2010-06-11 15:38:17 +00:00
|
|
|
#ifndef PNGLIBRARY_HXX
|
|
|
|
#define PNGLIBRARY_HXX
|
|
|
|
|
|
|
|
#include <png.h>
|
|
|
|
|
2018-03-24 15:06:00 +00:00
|
|
|
class OSystem;
|
2010-10-18 18:39:57 +00:00
|
|
|
class FrameBuffer;
|
|
|
|
class FBSurface;
|
2013-01-28 20:39:50 +00:00
|
|
|
class Properties;
|
2010-10-18 18:39:57 +00:00
|
|
|
|
2010-06-11 15:38:17 +00:00
|
|
|
#include "bspf.hxx"
|
|
|
|
|
|
|
|
/**
|
|
|
|
This class implements a thin wrapper around the libpng library, and
|
|
|
|
abstracts all the irrelevant details other loading and saving an
|
|
|
|
actual image.
|
|
|
|
|
|
|
|
@author Stephen Anthony
|
|
|
|
*/
|
|
|
|
class PNGLibrary
|
|
|
|
{
|
|
|
|
public:
|
2018-08-28 19:30:00 +00:00
|
|
|
explicit PNGLibrary(OSystem& osystem);
|
2010-06-11 15:38:17 +00:00
|
|
|
|
|
|
|
/**
|
2011-07-03 21:52:33 +00:00
|
|
|
Read a PNG image from the specified file into a FBSurface structure,
|
|
|
|
scaling the image to the surface bounds.
|
2010-06-11 15:38:17 +00:00
|
|
|
|
2013-01-28 20:39:50 +00:00
|
|
|
@param filename The filename to load the PNG image
|
2011-07-03 21:52:33 +00:00
|
|
|
@param surface The FBSurface into which to place the PNG data
|
2010-06-11 15:38:17 +00:00
|
|
|
|
2017-10-11 20:48:07 +00:00
|
|
|
@post On success, the FBSurface containing image data, otherwise a
|
|
|
|
runtime_error is thrown containing a more detailed
|
|
|
|
error message.
|
2010-06-11 15:38:17 +00:00
|
|
|
*/
|
2014-06-13 13:35:41 +00:00
|
|
|
void loadImage(const string& filename, FBSurface& surface);
|
2013-01-28 20:39:50 +00:00
|
|
|
|
|
|
|
/**
|
2015-06-12 20:44:09 +00:00
|
|
|
Save the current FrameBuffer image to a PNG file. Note that in most
|
|
|
|
cases this will be a TIA image, but it could actually be used for
|
|
|
|
*any* mode.
|
2013-01-28 20:39:50 +00:00
|
|
|
|
2014-06-13 13:35:41 +00:00
|
|
|
@param filename The filename to save the PNG image
|
2014-06-19 16:45:07 +00:00
|
|
|
@param comments The text comments to add to the PNG image
|
2014-06-13 13:35:41 +00:00
|
|
|
|
2017-10-11 20:48:07 +00:00
|
|
|
@post On success, the PNG file has been saved to 'filename',
|
|
|
|
otherwise a runtime_error is thrown containing a
|
|
|
|
more detailed error message.
|
2013-01-28 20:39:50 +00:00
|
|
|
*/
|
2014-06-19 16:45:07 +00:00
|
|
|
void saveImage(const string& filename,
|
|
|
|
const VariantList& comments = EmptyVarList);
|
2013-01-28 20:39:50 +00:00
|
|
|
|
|
|
|
/**
|
2014-06-19 16:45:07 +00:00
|
|
|
Save the given surface to a PNG file.
|
2014-06-13 13:35:41 +00:00
|
|
|
|
2014-06-19 16:45:07 +00:00
|
|
|
@param filename The filename to save the PNG image
|
|
|
|
@param surface The surface data for the PNG image
|
|
|
|
@param rect The area of the surface to use
|
|
|
|
@param comments The text comments to add to the PNG image
|
2013-01-28 20:39:50 +00:00
|
|
|
|
2017-10-11 20:48:07 +00:00
|
|
|
@post On success, the PNG file has been saved to 'filename',
|
|
|
|
otherwise a runtime_error is thrown containing a
|
|
|
|
more detailed error message.
|
2013-01-28 20:39:50 +00:00
|
|
|
*/
|
2014-06-19 16:45:07 +00:00
|
|
|
void saveImage(const string& filename, const FBSurface& surface,
|
2019-05-02 20:28:39 +00:00
|
|
|
const Common::Rect& rect = Common::EmptyRect,
|
2014-06-19 16:45:07 +00:00
|
|
|
const VariantList& comments = EmptyVarList);
|
2010-06-15 15:40:11 +00:00
|
|
|
|
2018-03-24 15:06:00 +00:00
|
|
|
/**
|
|
|
|
Called at regular intervals, and used to determine whether a
|
|
|
|
continuous snapshot is due to be taken.
|
|
|
|
|
|
|
|
@param time The current time in microseconds
|
|
|
|
*/
|
|
|
|
void updateTime(uInt64 time);
|
|
|
|
|
|
|
|
/**
|
|
|
|
Answer whether continuous snapshot mode is enabled.
|
|
|
|
*/
|
|
|
|
bool continuousSnapEnabled() const { return mySnapInterval > 0; }
|
|
|
|
|
|
|
|
/**
|
|
|
|
Enable/disable continuous snapshot mode.
|
|
|
|
|
|
|
|
@param perFrame Toggle snapshots every frame, or that specified by
|
|
|
|
'ssinterval' setting.
|
|
|
|
*/
|
|
|
|
void toggleContinuousSnapshots(bool perFrame);
|
|
|
|
|
|
|
|
/**
|
|
|
|
Set the number of seconds between taking a snapshot in
|
|
|
|
continuous snapshot mode. Setting an interval of 0 disables
|
|
|
|
continuous snapshots.
|
|
|
|
|
|
|
|
@param interval Interval in seconds between snapshots
|
|
|
|
*/
|
|
|
|
void setContinuousSnapInterval(uInt32 interval);
|
|
|
|
|
|
|
|
/**
|
2018-12-07 18:52:39 +00:00
|
|
|
NOTE: This method will be made private soon, so all calls from
|
|
|
|
external code should be refactored
|
|
|
|
|
2018-03-24 15:06:00 +00:00
|
|
|
Create a new snapshot based on the name of the ROM, and also
|
|
|
|
optionally using the number given as a parameter.
|
|
|
|
|
|
|
|
@param number Optional number to append to the snapshot name
|
|
|
|
*/
|
|
|
|
void takeSnapshot(uInt32 number = 0);
|
|
|
|
|
2010-06-15 15:40:11 +00:00
|
|
|
private:
|
2018-03-24 15:06:00 +00:00
|
|
|
// Global OSystem object
|
|
|
|
OSystem& myOSystem;
|
|
|
|
|
|
|
|
// Used for continuous snapshot mode
|
2019-12-29 00:44:52 +00:00
|
|
|
uInt32 mySnapInterval{0};
|
|
|
|
uInt32 mySnapCounter{0};
|
2014-06-13 13:35:41 +00:00
|
|
|
|
2011-07-03 21:52:33 +00:00
|
|
|
// The following data remains between invocations of allocateStorage,
|
|
|
|
// and is only changed when absolutely necessary.
|
2014-11-07 00:31:46 +00:00
|
|
|
struct ReadInfoType {
|
2019-12-28 21:14:50 +00:00
|
|
|
vector<png_byte> buffer;
|
|
|
|
vector<png_bytep> row_pointers;
|
2019-12-29 00:44:52 +00:00
|
|
|
png_uint_32 width{0}, height{0}, pitch{0};
|
2014-11-07 00:31:46 +00:00
|
|
|
};
|
2011-07-03 21:52:33 +00:00
|
|
|
static ReadInfoType ReadInfo;
|
|
|
|
|
2010-06-15 15:40:11 +00:00
|
|
|
/**
|
2011-07-03 21:52:33 +00:00
|
|
|
Allocate memory for PNG read operations. This is used to provide a
|
|
|
|
basic memory manager, so that we don't constantly allocate and deallocate
|
|
|
|
memory for each image loaded.
|
|
|
|
|
|
|
|
The method fills the 'ReadInfo' struct with valid memory locations
|
|
|
|
dependent on the given dimensions. If memory has been previously
|
|
|
|
allocated and it can accommodate the given dimensions, it is used directly.
|
2014-06-13 13:35:41 +00:00
|
|
|
|
|
|
|
@param iwidth The width of the PNG image
|
|
|
|
@param iheight The height of the PNG image
|
2011-07-03 21:52:33 +00:00
|
|
|
*/
|
|
|
|
bool allocateStorage(png_uint_32 iwidth, png_uint_32 iheight);
|
|
|
|
|
2014-06-19 16:45:07 +00:00
|
|
|
/** The actual method which saves a PNG image.
|
|
|
|
|
|
|
|
@param out The output stream for writing PNG data
|
2016-01-24 17:42:44 +00:00
|
|
|
@param rows Pointer into PNG RGB data for each row
|
2014-06-19 16:45:07 +00:00
|
|
|
@param width The width of the PNG image
|
|
|
|
@param height The height of the PNG image
|
|
|
|
@param comments The text comments to add to the PNG image
|
|
|
|
*/
|
2019-12-28 21:14:50 +00:00
|
|
|
void saveImageToDisk(ofstream& out, const vector<png_bytep>& rows,
|
2018-12-07 18:52:39 +00:00
|
|
|
png_uint_32 width, png_uint_32 height,
|
|
|
|
const VariantList& comments);
|
2014-06-19 16:45:07 +00:00
|
|
|
|
2011-07-03 21:52:33 +00:00
|
|
|
/**
|
2014-08-28 14:21:44 +00:00
|
|
|
Load the PNG data from 'ReadInfo' into the FBSurface. The surface
|
|
|
|
is resized as necessary to accommodate the data.
|
2010-06-15 15:40:11 +00:00
|
|
|
|
2014-06-13 13:35:41 +00:00
|
|
|
@param surface The FBSurface into which to place the PNG data
|
2010-06-15 15:40:11 +00:00
|
|
|
*/
|
2014-08-28 14:21:44 +00:00
|
|
|
void loadImagetoSurface(FBSurface& surface);
|
2010-06-15 15:40:11 +00:00
|
|
|
|
2014-06-13 13:35:41 +00:00
|
|
|
/**
|
|
|
|
Write PNG tEXt chunks to the image.
|
|
|
|
*/
|
|
|
|
void writeComments(png_structp png_ptr, png_infop info_ptr,
|
2014-06-19 16:45:07 +00:00
|
|
|
const VariantList& comments);
|
2013-01-28 20:39:50 +00:00
|
|
|
|
2014-06-13 13:35:41 +00:00
|
|
|
/** PNG library callback functions */
|
2010-06-15 15:40:11 +00:00
|
|
|
static void png_read_data(png_structp ctx, png_bytep area, png_size_t size);
|
|
|
|
static void png_write_data(png_structp ctx, png_bytep area, png_size_t size);
|
|
|
|
static void png_io_flush(png_structp ctx);
|
2017-10-11 14:53:54 +00:00
|
|
|
[[noreturn]] static void png_user_warn(png_structp ctx, png_const_charp str);
|
|
|
|
[[noreturn]] static void png_user_error(png_structp ctx, png_const_charp str);
|
2015-04-26 19:02:42 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
// Following constructors and assignment operators not supported
|
2019-12-29 02:06:40 +00:00
|
|
|
PNGLibrary() = delete;
|
2015-04-26 19:02:42 +00:00
|
|
|
PNGLibrary(const PNGLibrary&) = delete;
|
|
|
|
PNGLibrary(PNGLibrary&&) = delete;
|
|
|
|
PNGLibrary& operator=(const PNGLibrary&) = delete;
|
|
|
|
PNGLibrary& operator=(PNGLibrary&&) = delete;
|
2010-06-11 15:38:17 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|
2019-05-02 20:28:39 +00:00
|
|
|
|
|
|
|
#endif // PNG_SUPPORT
|